当使用 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;