近来一直在测试MySQL的XA事务,至于什么是XA,想必大家都比较清楚了,这次不再过多解释。
实际上,XA在MySQL中用的不是很多,其中有很大原因是以前的版本,譬如5.6,在xa方面,还有很多的问题,比如,binlog不记录xa prepare,导致主从数据不一致,到了5.7,官方在这方面已经做了很多的改进,但问题还是仍然存在的,以下就其中一个bug做以简单描述。
下边就开始喽,眼睛不要眨了
step1 运行高并发的模拟脚本。
step2 趁着这热乎劲,觉得爽了,就kill mysql(master)的实例,要稳准狠。
step3 是不是开始报失去连接了,然后就可以喝点水,准备启动kill掉的实例了。
此次丢失的XA事务涉及两个节点(端口为3711,3714);
主从端口是一致的,比如主端口3711,从端口也是3711;
MASTER3711代表主库,端口3711;
SLAVE3711,代表从库,端口3711;
图1 MASTER3711的XID列表以及状态
然后,我们把这写XID都处理掉
图2 日志显示
好了,MASTER3711 已经清净了,不过到这,事情才刚刚开始。
图3 MASTER3711/SLAVE3711 的XID悬挂如下所示
图3(一)MASTER 37111XID悬挂
图3 (二)SLAVE3711 的XID悬挂
有没有发现,SALVE3711还留了一个XID,这个怎么就多了一个呢?
其实,这个XID从截图1/2中可以发现,木有啊,再梳理一下这个过程。
看到这个XID,PREPARE是OK的,已经到了COMMIT阶段。
3711失败,3714成功。
截图5 MASTER3711/MASTER3714 BINLOG如下图所示。
图 5 MASTER3711 BINLOG
图 6 MASTER3714 BINLOG
图7 SLAVE 3711
如图7所示, SLAVE3711BINLOG信息与主库是一致的,但主库在RECOVER的时候,就找不到这个XID了。
简单总结,这个XID,一个主丢了,一个主COMMIT了,一个从PREPARE了。就问你们,乱不乱,乱不乱。
那么,这个SALVE3711怎么对待这个XID呢??是COMMIT?还是ROLLBACK??你自己决定吧。
其实吧,就算MASTER没有丢XID,一个都没丢,一旦出现悬挂,主从还是复制终止的,为什么?,你猜?(给你个提示码1397)