今天测试在已开启GTID的情况下的binlog复制切换到GTID复制,遇到个问题,记录下来。

场景是:主库和从库分别开启GTID模式,主库创建一个库和一张表并写入数据;主库mysqldump使用了--set-gtid-purged=OFF即不记录GTID事务编号做完备,导入到从库

 

从库show slave status\G看到的状态应该是这样

已开启GTID的情况下的binlog复制切换到GTID复制可能会遇到的问题_MySQL

而主库上show master status;看到的结果是

已开启GTID的情况下的binlog复制切换到GTID复制可能会遇到的问题_MySQL_02

此时如果直接切换到GTID复制,你会发现复制分报错

已开启GTID的情况下的binlog复制切换到GTID复制可能会遇到的问题_MySQL_03已开启GTID的情况下的binlog复制切换到GTID复制可能会遇到的问题_MySQL_04

我们知道

Retrieved_Gtid_Set是指定从库接收到的GTID集合

Executed_Gtid_Set是已执行的GTID集合

对比可以发现

切换GTID复制以后,主库会把从库没有的GTID发送给从库,而从库接收到这些GTID后,按顺序执行,当执行到第一个GTID时就发生报错,原因是从库已经执行过这个GTID的SQL语句(创建表);这个问题的解决办法是从库的master信息并跳过已经执行的GTID

root@localhost [(none)]>reset master;
Query OK, 0 rows affected (0.13 sec)

root@localhost [(none)]>set global gtid_purged='d26fd29a-b7d4-11e6-b38e-00155d7b0100:1-14';
Query OK, 0 rows affected (0.00 sec)

root@localhost [(none)]>start slave;

 

最后主从复制恢复,同时可以看到复制状态

已开启GTID的情况下的binlog复制切换到GTID复制可能会遇到的问题_MySQL_05

 

总结一下,在已开启GTID的情况下的binlog复制切换到GTID复制的步骤:

主库执行show master status并记录Executed_Gtid_Set的开始位置

已开启GTID的情况下的binlog复制切换到GTID复制可能会遇到的问题_MySQL_06

从上图可以看出我的环境的Executed_Gtid_Set集合从1开始

从库导入数执行change master to语句,设置成binlog复制模式,看下复制是否成功,如果成功,把复制停掉,执行reset master后再执行show slave status\G, 可以看到当前已接收到的GTID集合,记录下集群的结束位置是15

已开启GTID的情况下的binlog复制切换到GTID复制可能会遇到的问题_MySQL_07

从库执行set global gtid_purged='d26fd29a-b7d4-11e6-b38e-00155d7b0100:1-15';

再执行show slave status\G可以看到

已开启GTID的情况下的binlog复制切换到GTID复制可能会遇到的问题_MySQL_08

可以看出主从库Executed_Gtid_Set是一样的


问题?

如果主库在初始化完成后马上做完备,这种情况下会有这个问题吗?