在使用 MySQL 复制与全局事务标识符 (GTID) 时,有许多技术可以用来配置新的副本,然后可以将其用于横向扩展,并在需要时提升为源以进行故障转移。本节介绍以下技术:
全局事务标识符被添加到 MySQL 复制中,其目的是简化复制数据流的总体管理,尤其是故障转移活动的管理。每个标识符都唯一地标识一组构成事务的二进制日志事件。GTID 在将更改应用于数据库方面发挥着关键作用:服务器会自动跳过任何具有服务器识别为之前已处理过的标识符的事务。此行为对于自动复制定位和正确故障转移至关重要。
标识符与构成给定事务的事件集之间的映射在二进制日志中捕获。这在为新服务器配置来自另一个现有服务器的数据时带来了一些挑战。为了在新服务器上复制标识符集,需要将标识符从旧服务器复制到新服务器,并保留标识符与实际事件之间的关系。这是恢复立即可用作故障转移或切换时成为新源的候选者的副本所必需的。
简单复制。 在新的服务器上复制所有标识符和事务的最简单方法是将新的服务器设置为具有完整执行历史记录的源的副本,并在两个服务器上启用全局事务标识符。有关更多信息,请参见第 19.1.3.4 节“使用 GTID 设置复制”。
启动复制后,新的服务器会从源复制整个二进制日志,从而获得有关所有 GTID 的所有信息。
此方法简单有效,但需要副本从源读取二进制日志;新副本有时可能需要较长时间才能赶上源,因此此方法不适合快速故障转移或从备份恢复。本节说明如何通过将二进制日志文件复制到新服务器来避免从源获取所有执行历史记录。
将数据和事务复制到副本。 当源服务器之前已处理了大量事务时,执行整个事务历史记录可能非常耗时,这在设置新副本时可能会成为主要瓶颈。为了消除此要求,可以将源服务器包含的数据集、二进制日志和全局事务信息的快照导入到新的副本中。进行快照的服务器可以是源服务器或其副本之一,但必须确保服务器已处理所有必需的事务,然后才能复制数据。
此方法有几种变体,区别在于数据转储和二进制日志中的事务传输到副本的方式,如下所述:
- 数据集
-
在源服务器上使用 mysqldump 创建转储文件。将 mysqldump 选项
--source-data
设置为 1,以包含带有二进制日志信息的CHANGE REPLICATION SOURCE TO
语句。将--set-gtid-purged
选项设置为AUTO
(默认值)或ON
,以在转储中包含有关已执行事务的信息。然后使用 mysql 客户端在目标服务器上导入转储文件。或者,使用原始数据文件创建源服务器的数据快照,然后按照 第 19.1.2.5 节,“选择数据快照方法” 中的说明将这些文件复制到目标服务器。如果您使用
InnoDB
表,可以使用 MySQL Enterprise Backup 组件中的 mysqlbackup 命令生成一致的快照。此命令会记录与快照相对应的日志名称和偏移量,以便在副本上使用。MySQL Enterprise Backup 是一款商业产品,包含在 MySQL Enterprise 订阅中。有关详细信息,请参见 第 32.1 节,“MySQL Enterprise Backup 概述”。或者,停止源服务器和目标服务器,将源服务器的数据目录内容复制到新副本的数据目录,然后重新启动副本。如果您使用此方法,副本必须配置为基于 GTID 的复制,换句话说,使用
gtid_mode=ON
。有关此方法的说明和重要信息,请参见 第 19.1.2.8 节,“将副本添加到复制环境”。
- 事务历史记录
如果源服务器在其二进制日志中具有完整的事务历史记录(即,GTID 集
@@GLOBAL.gtid_purged
为空),您可以使用这些方法。使用 mysqlbinlog 将源服务器的二进制日志导入到新副本,并使用
--read-from-remote-server
和--read-from-remote-source
选项。或者,将源服务器的二进制日志文件复制到副本。您可以使用 mysqlbinlog 并使用
--read-from-remote-server
和--raw
选项从副本创建副本。可以使用 mysqlbinlog>
(不带file
--raw
选项)将这些二进制日志文件导出到 SQL 文件,然后将这些文件传递给 mysql 客户端进行处理。确保使用单个 mysql 进程而不是多个连接来处理所有二进制日志文件。例如$> mysqlbinlog copied-binlog.000001 copied-binlog.000002 | mysql -u root -p
有关更多信息,请参见 第 6.6.9.3 节,“使用 mysqlbinlog 备份二进制日志文件”。
此方法的优势在于几乎可以立即使用新服务器;只有在快照或转储文件正在重放时提交的事务才需要从现有源中获取。这意味着副本的可用性不是即时的,但副本应该只需要相对较短的时间才能赶上这几个剩余的事务。
提前将二进制日志复制到目标服务器通常比实时从源读取整个事务执行历史记录更快。但是,由于大小或其他原因,在需要时可能无法将这些文件移动到目标。本节讨论的用于配置新副本的另外两种方法使用其他方法将有关事务的信息传输到新副本。
注入空事务。 源的全局 gtid_executed
变量包含在源上执行的所有事务集。在使用快照配置新服务器时,您可以记录从其中获取快照的服务器上的 gtid_executed
内容,而不是复制二进制日志。在将新服务器添加到复制链之前,只需在新的服务器上为源的 gtid_executed
中包含的每个事务标识符提交一个空事务,如下所示
SET GTID_NEXT='aaa-bbb-ccc-ddd:N';
BEGIN;
COMMIT;
SET GTID_NEXT='AUTOMATIC';
以这种方式使用空事务恢复所有事务标识符后,您必须刷新和清除副本的二进制日志,如下所示,其中 N
是当前二进制日志文件名中的非零后缀
FLUSH LOGS;
PURGE BINARY LOGS TO 'source-bin.00000N';
您应该这样做,以防止此服务器在稍后被提升为源时,用错误的事务淹没复制流。(FLUSH LOGS
语句会强制创建新的二进制日志文件;PURGE BINARY LOGS
会清除空事务,但会保留其标识符。)
此方法创建的服务器本质上是一个快照,但随着时间的推移,它的二进制日志历史记录会与复制流收敛(即,随着它赶上源或其他源),它能够成为源。此结果在效果上类似于使用剩余的配置方法获得的结果,我们将在接下来的几段中讨论。
排除使用 gtid_purged 的事务。 源的全局 gtid_purged
变量包含已从源的二进制日志中清除的所有事务集。与之前讨论的方法一样(参见 注入空事务),您可以记录从其中获取快照的服务器上的 gtid_executed
的值(代替将二进制日志复制到新服务器)。与之前的方法不同,无需提交空事务(或发出 PURGE BINARY LOGS
);相反,您可以根据从其中获取备份或快照的服务器上的 gtid_executed
值,直接在副本上设置 gtid_purged
。
与使用空事务的方法一样,此方法创建的服务器在功能上是一个快照,但随着时间的推移,它的二进制日志历史记录会与源和其他副本的复制流收敛。
恢复 GTID 模式副本。 在恢复基于 GTID 的复制设置中的副本时,如果该副本遇到了错误,注入空事务可能无法解决问题,因为事件没有 GTID。
使用 mysqlbinlog 查找下一个事务,它可能是事件之后的下一个日志文件中的第一个事务。复制直到该事务的 COMMIT
的所有内容,确保包含 SET @@SESSION.gtid_next
。即使您没有使用基于行的复制,您仍然可以在命令行客户端中运行二进制日志行事件。
停止副本并运行您复制的事务。 mysqlbinlog 输出将分隔符设置为 /*!*/;
,因此将其设置回默认值,如下所示
mysql> DELIMITER ;
自动从正确的位置重新启动复制
mysql> SET gtid_next=AUTOMATIC;
mysql> RESET REPLICA;
mysql> START REPLICA;