16.1.3.5 使用 GTID 进行故障转移和横向扩展

当使用带有全局事务标识符(GTID)的 MySQL 复制来提供新副本时,可以使用多种技术进行复制,然后将其用于横向扩展,并根据需要将其升级为源以进行故障转移。本节介绍以下技术:

全局事务标识符已添加到 MySQL 复制中,目的是简化复制数据流的常规 Management,尤其是简化故障转移活动。每个标识符唯一标识一组二进制日志事件,这些事件共同构成一个事务。 GTID 在将更改应用于数据库中起着关键作用:服务器自动跳过任何具有标识符的事务,该标识符被服务器识别为之前已处理过的事务。此行为对于自动复制定位和正确的故障转移至关重要。

标识符和包含给定事务的事件集之间的 Map 在二进制日志中捕获。在为新服务器提供来自其他现有服务器的数据时,这会带来一些挑战。为了再现在新服务器上设置的标识符,必须将标识符从旧服务器复制到新服务器,并保留标识符和实际事件之间的关系。这对于还原可立即用作候选副本的副本,以使其成为故障转移或切换时的新来源是必要的。

简单复制. 在新服务器上重现所有标识符和事务的最简单方法是使新服务器成为具有完整执行历史记录的源副本,并在两个服务器上启用全局事务标识符。有关更多信息,请参见第 16.1.3.4 节,“使用 GTID 设置复制”

复制开始后,新服务器将从源复制整个二进制日志,从而获得有关所有 GTID 的所有信息。

这种方法简单有效,但是需要副本从源中读取二进制日志。有时新副本要赶上源副本可能要花比较长的时间,因此此方法不适用于快速故障转移或从备份还原。本节说明如何通过将二进制日志文件复制到新服务器来避免从源中获取所有执行历史记录。

将数据和事务复制到副本. 当源服务器以前处理大量事务时,执行整个事务历史记录可能很耗时,这可能是设置新副本时的主要瓶颈。为了消除此要求,可以将源服务器包含的数据集快照,二进制日志和全局事务信息导入到新副本中。源服务器可以是源服务器,也可以是副本服务器,但是在复制数据之前,必须确保源服务器已处理所有必需的事务。

此方法有多种变体,区别在于将二进制日志中的数据转储和事务传输到副本的方式,如下所示:

  • Data Set

      • 在源服务器上使用mysqldump创建转储文件。设置mysqldump选项--master-data(默认值为 1)以包含带有二进制日志记录信息的更改为主语句。将--set-gtid-purged选项设置为AUTO(默认值)或ON,以在转储中包含有关已执行事务的信息。然后,使用mysqlClient 端将转储文件导入目标服务器上。
  • 或者,使用原始数据文件创建源服务器的数据快照,然后按照第 16.1.2.4 节,“选择数据快照的方法”中的说明将这些文件复制到目标服务器。如果使用InnoDBtable,则可以使用 MySQL Enterprise Backup 组件中的 mysqlbackup 命令生成一致的快照。此命令记录与要在副本上使用的快照相对应的日志名称和偏移量。 MySQL Enterprise Backup 是商业产品,包含在 MySQL Enterprise 订阅中。有关详细信息,请参见第 29.2 节“ MySQL 企业备份概述”

  • 或者,停止源服务器和目标服务器,将源数据目录的内容复制到新副本的数据目录,然后重新启动副本。如果使用此方法,则必须为基于 GTID 的复制配置副本,即使用gtid_mode=ON。有关此方法的说明和重要信息,请参见第 16.1.2.6 节,“将副本添加到复制拓扑”

  • Transaction History

    • 如果源服务器在其二进制日志中具有完整的事务历史记录(即 GTID 集@@GLOBAL.gtid_purged为空),则可以使用这些方法。
  • 使用--read-from-remote-server--read-from-remote-master选项,使用mysqlbinlog将二进制日志从源服务器导入到新副本。

  • 或者,将源服务器的二进制日志文件复制到副本。您可以使用mysqlbinlog--read-from-remote-server--raw选项从副本中复制副本。可以使用mysqlbinlog > file(不带--raw选项)将这些文件读入副本,以将二进制日志文件导出为 SQL 文件,然后将这些文件传递给mysqlClient 端进行处理。确保使用单个mysql进程而不是多个连接来处理所有二进制日志文件。例如:

shell> mysqlbinlog copied-binlog.000001 copied-binlog.000002 | mysql -u root -p

有关更多信息,请参见第 4.6.7.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语句强制创建新的二进制日志文件; 清除二进制日志清除空事务,但保留其标识符。)

此方法创建的服务器本质上是快照,但由于其二进制日志历史记录与复制流的二进制日志历史记录收敛(即,它追赶一个或多个源文件),因此能够及时成为源文件。该结果实际上与使用其余配置方法获得的结果相似,我们将在接下来的几段中讨论该结果。

不包括具有 gtid_purged 的事务. 源的全局gtid_purged变量包含已从源的二进制日志中清除的所有事务的集合。与前面讨论的方法一样(请参见注入空 Transaction),您可以在获取快照的服务器上记录gtid_executed的值(代替将二进制日志复制到新服务器上)。与以前的方法不同,无需提交空事务(或发出清除二进制日志);相反,您可以根据从中获取备份或快照的服务器上gtid_executed的值直接在副本上设置gtid_purged

与使用空事务的方法一样,此方法创建的服务器在功能上是快照,但由于其二进制日志历史记录与复制源服务器或组的二进制日志历史记录收敛,因此可以及时成为源。

还原 GTID 模式副本. 在遇到错误的基于 GTID 的复制设置中恢复副本时,注入空事务可能无法解决问题,因为事件没有 GTID。

使用mysqlbinlog查找下一个事务,它可能是事件之后下一个日志文件中的第一个事务。将所有内容复制到该 Transaction 的COMMIT,并确保包括SET @@SESSION.GTID_NEXT。即使您没有使用基于行的复制,您仍然可以在命令行 Client 端中运行二进制日志行事件。

停止副本并运行您复制的事务。 mysqlbinlog输出将定界符设置为/*!*/;,因此将其设置回:

mysql> DELIMITER ;

自动从正确的位置重新启动复制:

mysql> SET GTID_NEXT=automatic;
mysql> RESET SLAVE;
mysql> START SLAVE;