文档首页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  为基于 GTID 的复制准备多源副本

19.1.5.2 为基于 GTID 的复制准备多源副本

如果多源复制拓扑中的源存在现有数据,则在启动复制之前使用相关数据准备副本可以节省时间。在多源复制拓扑中,不能使用数据目录的克隆或复制来使用来自所有源的数据准备副本,并且您可能还希望仅从每个源复制特定的数据库。因此,准备此类副本的最佳策略是使用 mysqldump 在每个源上创建适当的转储文件,然后使用 mysql 客户端将转储文件导入副本。

如果您使用的是基于 GTID 的复制,则需要注意 mysqldump 在转储输出中放置的 SET @@GLOBAL.gtid_purged 语句。此语句将源上执行的事务的 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 集与第一个转储中的 GTID 集相同(因此在两个转储之间,源上没有执行新的事务),那么您可以在导出第二个转储文件时设置 --set-gtid-purged=OFF,以省略该语句。

在以下配置示例中,我们假设 SET @@GLOBAL.gtid_purged 语句不能保留在转储输出中,必须从文件中移除并手动处理。我们还假设在配置开始之前,副本上没有想要的带有 GTID 的事务。

  1. 要为 source1 上名为 db1 的数据库和 source2 上名为 db2 的数据库创建转储文件,请针对 source1 运行 mysqldump,如下所示

    mysqldump -u<user> -p<password> --single-transaction --triggers --routines --set-gtid-purged=ON --databases db1 > dumpM1.sql

    然后针对 source2 运行 mysqldump,如下所示

    mysqldump -u<user> -p<password> --single-transaction --triggers --routines --set-gtid-purged=ON --databases db2 > dumpM2.sql
  2. 记录 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
  3. 从每个转储文件中移除包含 SET @@GLOBAL.gtid_purged 语句的行。例如

    sed '/GTID_PURGED/d' dumpM1.sql > dumpM1_nopurge.sql
    sed '/GTID_PURGED/d' dumpM2.sql > dumpM2_nopurge.sql
  4. 使用 mysql 客户端将每个已编辑的转储文件导入副本。例如

    mysql -u<user> -p<password> < dumpM1_nopurge.sql
    mysql -u<user> -p<password> < dumpM2_nopurge.sql
  5. 在副本上,发出 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 集的并集。