暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【ACDU翻译】 MySQL 17.1.5.2 为基于 GTID 的复制提供多源副本

原创 由迪 2022-08-18
321

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

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

与 MySQL 5.6 和 5.7 相比,mysqldumpSET @@GLOBAL.gtid_purged 编写 的语句的行为在 MySQL 8.0 的版本中有所不同。在 MySQL 5.6 和 5.7 中,该语句替换 副本上的值,并且在那些版本中,该值只能在副本的具有 GTID( 集合)的事务记录为空时更改。因此,在多源复制拓扑中,您必须删除 gtid_purgedgtid_executedSET @@GLOBAL.gtid_purged在重播转储文件之前从转储输出中提取语句,因为您无法应用包含此语句的第二个或后续转储文件。另请注意,对于 MySQL 5.6 和 5.7,此限制意味着来自源的所有转储文件必须在具有空 gtid_executed集的副本上的单个操作中应用。您可以通过在副本上发布来清除副本的 GTID 执行历史记录 RESET MASTER,但如果您在副本上有其他需要使用 GTID 的事务,请从第 17.1.3.5 节“使用 GTID 进行故障转移和横向扩展”中描述的方法中选择一种替代方法”

从 MySQL 8.0 开始,该SET @@GLOBAL.gtid_purged 语句将转储文件中的 GTID 集添加到 gtid_purged副本上的现有集。因此,当您在副本上重放转储文件时,该语句可能会留在转储输出中,并且可以在不同时间重放转储文件。但是,重要的是要注意 mysqldumpSET @@GLOBAL.gtid_purged语句包含的值包括所有事务的 GTIDgtid_executed 在源上设置,即使那些更改了数据库的抑制部分,或服务器上未包含在部分转储中的其他数据库。如果您在包含任何相同 GTID 的副本上重放第二个或后续转储文件(例如,来自同一源的另一个部分转储,或来自具有重叠事务的另一个源的转储),SET @@GLOBAL.gtid_purged则第二个转储文件中的任何语句失败,因此必须从转储输出中删除。

对于来自 MySQL 8.0.17 的源,作为删除 SET @@GLOBAL.gtid_purged语句的替代方法,您可以将 mysqldump--set-gtid-purged选项设置 COMMENTED为包含该语句但将其注释掉,以便在加载转储文件时不会对其进行操作。如果您使用来自同一源的两个部分转储来配置副本,并且第二个转储中设置的 GTID 与第一个相同(因此在转储之间的源上没有执行任何新事务),您可以设置 mysqldump--set-gtid-purged选项, OFF当您输出第二个转储文件时,省略该语句。

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

  1. db1要为名为onsource1的数据库和名为db2on 的 数据库创建转储文件 source2,请运行mysqldump for source1,如下所示:

    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
    
    复制
  2. 记录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$'\''
    
    复制

    从 MySQL 8.0 中,格式已更改,您可以像这样提取值:

    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 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 集之间存在或可能存在重叠事务,您可以使用 第 17.1.3.8 节“操作 GTID 的存储函数示例”中描述的存储函数预先检查并计算并集所有 GTID 集。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论