16.1.5.2 为基于 GTID 的复制配置多源副本

如果多源复制拓扑中的源具有现有数据,则可以节省时间在开始复制之前为副本提供相关数据。在多源复制拓扑中,不能使用复制数据目录为副本提供来自所有源的数据,并且您可能还希望仅复制来自每个源的特定数据库。因此,提供这种副本的最佳策略是使用mysqldump在每个源上创建适当的转储文件,然后使用mysqlClient 端将副本中的转储文件导入。

如果使用基于 GTID 的复制,则需要注意mysqldump放在转储输出中的SET @@GLOBAL.gtid_purged语句。该语句将在源上执行的事务的 GTID 传输到副本,副本需要此信息。但是,对于比从一个源配置一个新的空副本更为复杂的情况,您需要检查该语句在副本的 MySQL 版本中将产生什么影响,并相应地处理该语句。以下指南概述了适当的操作,但是有关更多详细信息,请参见mysqldump文档。

在 MySQL 5.6 和 5.7 中,由mysqldump编写的SET @@GLOBAL.gtid_purged语句替换副本上gtid_purged的值。同样,在那些发行版中,只有当副本的具有 GTID(设置为gtid_executed)的事务记录为空时,才能更改该值。因此,在多源复制拓扑中,必须在重播转储文件之前从转储输出中删除SET @@GLOBAL.gtid_purged语句,因为您将无法应用包含此语句的第二个或后续转储文件。作为删除SET @@GLOBAL.gtid_purged语句的替代方法,如果要为副本提供来自同一源的两个部分转储,并且在第二个转储中设置的 GTID 与第一个转储相同(因此,不会在源中执行新的事务)在转储之间),可以在输出第二个转储文件时将mysqldump--set-gtid-purged选项设置为OFF,以省略该语句。

对于 MySQL 5.6 和 5.7,这些限制意味着来自源的所有转储文件必须在具有空gtid_executed设置的副本上一次应用。您可以通过在副本上发出RESET MASTER来清除副本的 GTID 执行历史记录,但是如果您在副本上还有其他带有 GTID 的想要的事务,请从第 16.1.3.5 节,“使用 GTID 进行故障转移和横向扩展”中所述的替代方法中进行选择。

在以下配置示例中,我们假设需要从文件中删除SET @@GLOBAL.gtid_purged语句并手动对其进行处理。我们还假设在供应开始之前副本上不存在带有 GTID 的有用事务。

  • 要为source1上名为db1的数据库和source2上名为db2的数据库创建转储文件,请对source1运行mysqldump,如下所示:
mysqldump -u<user> -p<password> --single-transaction --triggers --routines --set-gtid-purged=ON --databases db1 > dumpM1.sql

然后按照以下步骤运行mysqldumpsource2

mysqldump -u<user> -p<password> --single-transaction --triggers --routines --set-gtid-purged=ON --databases db2 > dumpM2.sql
  • 记录mysqldump添加到每个转储文件中的gtid_purged值。例如,对于在 MySQL 5.6 或 5.7 上创建的转储文件,可以提取如下值:
cat dumpM1.sql | grep GTID_PURGED | cut -f2 -d'=' | cut -f2 -d$'\''
cat dumpM2.sql | grep GTID_PURGED | cut -f2 -d'=' | cut -f2 -d$'\''

每种情况下的结果都应该是 GTID 集,例如:

source1:   2174B383-5441-11E8-B90A-C80AA9429562:1-1029
source2:   224DA167-0C0C-11E8-8442-00059A3C7B00:1-2695
  • 从每个包含SET @@GLOBAL.gtid_purged语句的转储文件中删除该行。例如:
sed '/GTID_PURGED/d' dumpM1.sql > dumpM1_nopurge.sql
sed '/GTID_PURGED/d' dumpM2.sql > dumpM2_nopurge.sql
  • 使用mysqlClient 端将每个编辑的转储文件导入副本。例如:
mysql -u<user> -p<password> < dumpM1_nopurge.sql
mysql -u<user> -p<password> < dumpM2_nopurge.sql
  • 在副本上,发出RESET MASTER来清除 GTID 执行历史记录(如上所述,假设所有转储文件都已导入,并且副本上不存在带有 GTID 的有用事务)。然后发出SET @@GLOBAL.gtid_purged语句以将gtid_purged值设置为所有转储文件中所有 GTID 集的并集,如您在步骤 2 中记录的。例如:
mysql> RESET MASTER;
mysql> SET @@GLOBAL.gtid_purged = "2174B383-5441-11E8-B90A-C80AA9429562:1-1029, 224DA167-0C0C-11E8-8442-00059A3C7B00:1-2695";

如果转储文件中的 GTID 集之间存在(或可能存在)重叠事务,则可以使用第 16.1.3.7 节“用于操纵 GTID 的存储函数示例”中描述的存储函数预先进行检查并计算所有 GTID 集的并集。