今天测试在已开启GTID的情况下的binlog复制切换到GTID复制,遇到个问题,记录下来。
场景是:主库和从库分别开启GTID模式,主库创建一个库和一张表并写入数据;主库mysqldump使用了--set-gtid-purged=OFF即不记录GTID事务编号做完备,导入到从库
从库show slave status\G看到的状态应该是这样
而主库上show master status;看到的结果是
此时如果直接切换到GTID复制,你会发现复制分报错
我们知道
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复制的步骤:
主库执行show master status并记录Executed_Gtid_Set的开始位置
从上图可以看出我的环境的Executed_Gtid_Set集合从1开始
从库导入数执行change master to语句,设置成binlog复制模式,看下复制是否成功,如果成功,把复制停掉,执行reset master后再执行show slave status\G, 可以看到当前已接收到的GTID集合,记录下集群的结束位置是15
从库执行set global gtid_purged='d26fd29a-b7d4-11e6-b38e-00155d7b0100:1-15';
再执行show slave status\G可以看到
可以看出主从库Executed_Gtid_Set是一样的