如果多源复制拓扑结构中的源具有现有数据,可以在开始复制之前将副本配置为相关数据,以节省时间。在多源复制拓扑结构中,无法使用克隆或复制数据目录来配置副本的数据,而是从每个源复制特定的数据库。因此,配置这样的副本的最佳策略是使用 mysqldump 在每个源上创建适当的转储文件,然后使用 mysql 客户端在副本上导入转储文件。
如果您使用基于GTID的复制,需要注意 SET @@GLOBAL.gtid_purged
语句,该语句由 mysqldump 放置在转储输出中。该语句将源上的事务GTID传输到副本,副本需要该信息。但是,对于任何比从一个源配置一个新的空副本更复杂的情况,您需要检查该语句在副本使用的MySQL版本中的效果,并相应地处理该语句。以下指导总结了适当的操作,但为了获取更多详细信息,请参阅 mysqldump 文档。
SET @@GLOBAL.gtid_purged
将转储文件中的GTID集添加到副本上的现有 gtid_purged
集中。该语句因此可以在副本上重放转储文件时留在转储输出中,并且可以在不同的时间重放转储文件。然而,需要注意的是,mysqldump 为 SET @@GLOBAL.gtid_purged
语句包括了源上的所有事务GTID,包括更改了数据库的抑制部分或服务器上的其他数据库,这些数据库未包含在部分转储中。如果您在副本上重放第二个或后续转储文件,其中包含相同的GTID(例如,来自同一源的另一个部分转储或来自其他源的转储,具有重叠的事务),则任何 SET @@GLOBAL.gtid_purged
语句在第二个转储文件中将失败,必须因此从转储输出中删除。
作为删除 SET @@GLOBAL.gtid_purged
语句的替代方法,您可以使用 mysqldump 的 --set-gtid-purged=COMMENTED
选项,以便在转储输出中包含该语句,但将其括在SQL注释中,以便在加载转储文件时不执行。如果您使用两个来自同一源的部分转储来配置副本,并且第二个转储文件中的GTID集与第一个转储文件相同(因此,在两个转储之间没有在源上执行新事务),您可以在导出第二个转储文件时设置 --set-gtid-purged=OFF
,以便省略该语句。
在以下配置示例中,我们假设 SET @@GLOBAL.gtid_purged
语句不能留在转储输出中,必须从文件中删除并手动处理。我们还假设在配置开始之前副本上没有想要的事务GTID。
-
要为
db1
数据库在source1
上和db2
数据库在source2
上创建转储文件,运行 mysqldump 如下所示:mysqldump -u<user> -p<password> --single-transaction --triggers --routines --set-gtid-purged=ON --databases db1 > dumpM1.sql
然后,运行 mysqldump 对于
source2
如下所示:mysqldump -u<user> -p<password> --single-transaction --triggers --routines --set-gtid-purged=ON --databases db2 > dumpM2.sql
-
记录
gtid_purged
值,该值由 mysqldump 添加到每个转储文件中。您可以像这样提取该值:cat dumpM1.sql | grep GTID_PURGED | perl -p0 -e 's#/\*.*?\*/##sg' | cut -f2 -d'=' | cut -f2 -d$'\'' cat dumpM2.sql | grep GTID_PURGED | perl -p0 -e 's#/\*.*?\*/##sg' | 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
-
使用 mysql 客户端将每个编辑后的转储文件导入到副本中。例如:
mysql -u<user> -p<password> < dumpM1_nopurge.sql mysql -u<user> -p<password> < dumpM2_nopurge.sql
-
在副本上,发出
RESET BINARY LOGS AND GTIDS
以清除 GTID 执行历史记录(假设,如上所述,所有转储文件都已导入,并且副本上没有想要的带 GTID 的事务)。然后发出SET @@GLOBAL.gtid_purged
语句,以将gtid_purged
值设置为所有转储文件的 GTID 集合的并集,如步骤 2 中所记录的那样。例如:mysql> RESET BINARY LOGS AND GTIDS; mysql> SET @@GLOBAL.gtid_purged = "2174B383-5441-11E8-B90A-C80AA9429562:1-1029, 224DA167-0C0C-11E8-8442-00059A3C7B00:1-2695";
如果转储文件中的 GTID 集合之间存在或可能存在重叠的事务,可以使用 第 19.1.3.8 节,「用于操作 GTID 的存储函数示例」 中描述的存储函数来检查这之前,并计算所有 GTID 集合的并集。