• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 为基于GTID的复制配置多源复制从属服务器

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

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

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

    从MySQL 8.0开始,该SET @@GLOBAL.gtid_purged语句将转储文件中的GTID集添加到gtid_purged从属服务器上的现有集。因此,当您在从属服务器上重播转储文件时,该语句可能会留在转储输出中,并且转储文件可以在不同时间重播。但是,需要注意的是,mysqldump包含的SET @@GLOBAL.gtid_purged语句值包括了所有事务的GTID。gtid_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. 要创建转储文件名为数据库db1master1和指定的数据库db2master2运行的mysqldumpmaster1如下:

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

      然后运行mysqldumpmaster2如下所示:

      mysqldump -u<user> -p<password> --single-transaction --triggers --routines --set-gtid-purged=ON --databases db2 > dumpM2.sql
      
    2. 记录下gtid_purged该值的mysqldump添加到每个转储文件。例如,对于在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集,例如:

      master1:   2174B383-5441-11E8-B90A-C80AA9429562:1-1029
      master2:   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集之间存在(或可能存在)重叠事务,则可以使用“用于操作GTID的存储函数示例”中所述的存储函数预先进行检查并计算所有GTID集。