在上一篇中,我们使用如下方式跳过了5502这个event。那么为什么可以成功跳过呢?基于什么原理呢?
下面来简单阐述:
mysql> stop slave;
Query OK, 0 rows affected (0.09 sec)
mysql> set gtid_next="e2e2f927-e75c-11e5-ac89-5c260a17ccde:5502";
Query OK, 0 rows affected (0.00 sec)
mysql> begin;commit;
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.02 sec)
mysql> set gtid_next="AUTOMATIC";
Query OK, 0 rows affected (0.00 sec)
mysql> start slave;
Query OK, 0 rows affected (0.07 sec)
mysql>
执行set gtid_next="e2e2f927-e75c-11e5-ac89-5c260a17ccde:5502";之后,表示实例接下来的事务标记的gtid值为e2e2f927-e75c-11e5-ac89-5c260a17ccde:5502。
并且我们接下来执行的是begin;commit; 该语句不引起任何更改。同时我们commit之后,e2e2f927-e75c-11e5-ac89-5c260a17ccde:5502这个gtid的event结束。
接下来必须把gtid_next设置成AUTOMATIC,表示让slave生成自己的gtid值(因为e2e2f927-e75c-11e5-ac89-5c260a17ccde是master的uuid)。
此时如果我们看slave status的输出,在Retrieved_Gtid_Set和Executed_Gtid_Set中都有e2e2f927-e75c-11e5-ac89-5c260a17ccde:5502这个event。
表示slave端已经成功执行e2e2f927-e75c-11e5-ac89-5c260a17ccde:5502。
我们sql线程失败的原因是由于重演文件中e2e2f927-e75c-11e5-ac89-5c260a17ccde:5502的event无法执行导致,而我们又手工在slave端执行了e2e2f927-e75c-11e5-ac89-5c260a17ccde:5502的event。所以此时sql thread在启动时就会发现e2e2f927-e75c-11e5-ac89-5c260a17ccde:5502的event被执行了进而跳过重演文件中的e2e2f927-e75c-11e5-ac89-5c260a17ccde:5502事件。
基于gtid复制的最大特性就是slave端在重演时只判断gtid值和本地实际已经执行的gtid-sets进行比较,如果已经被包含,那么就会跳过。
这个特性在复制环境中是非常有用的。并且相比于binlog和pos的复制,gtid复制的可控性更强,在处理问题时更加灵活。