看mysql手册中关于 XA 模式下的行为描述时得知:
master节点执行xa prepare之后如果mysql crash了, 当mysql被恢复时可以通过命令xa recover 找到之前未完成提交的xa 事务,并且通过xa commit进行提交。但是这种情况下,
mysql是不会对这个xa事务记录binlog日志的。
之前看的时候还不是很明白为什么mysql要这么做,前几天测试mysql xa 模式下的主从复制时才明白这么做的原因。
测试中使用sysbench按照预先准备好的lua测试脚本,通过xa进行事务提交,所有的事务都是对测试表进行插入操作。
在sysbench压测过程中kill -9 master节点,然后停止sysbench脚本并恢复master节点,并xa rollback所有master恢复时通过xa recover能够查询到的xa 事务。
最后对比master和slave的数据。
测试过程中master和slave配置了半同步复制,按照我的预期,master和slave的数据应该只会有一条不一致,并且应该是master比slave多1行数据。
但最后的测试结果居然是slave比master多1行。 说明有一个xa事务在slave上提交了,而没有在master上提交。
通过查看并分析发现slave比master多的这行数据在master上进行提交的时候正好碰到了master 被kill -9,导致该xa事务没有完成,但 这个xa事务已经写完binlog了。。。
这应该就是mysql为什么对xa recover出来的xa 事务提交时不记录binlog的原因,怕重复记录!
但这就很难保证master和slave的数据一致性了,因为故障的时候slave得到的binlog上的事务可能在master上还没提交。
特别是如果主从一致的策略是丢弃master故障时未同步到slave上的事务时,当master恢复的时候应该进行xa commit还是xa rollback需要先去 slave上查看下该xa事务的binlog是否已经同步过来了。
转载请注明转自高孝鑫的博客
之前看的时候还不是很明白为什么mysql要这么做,前几天测试mysql xa 模式下的主从复制时才明白这么做的原因。
测试中使用sysbench按照预先准备好的lua测试脚本,通过xa进行事务提交,所有的事务都是对测试表进行插入操作。
在sysbench压测过程中kill -9 master节点,然后停止sysbench脚本并恢复master节点,并xa rollback所有master恢复时通过xa recover能够查询到的xa 事务。
最后对比master和slave的数据。
测试过程中master和slave配置了半同步复制,按照我的预期,master和slave的数据应该只会有一条不一致,并且应该是master比slave多1行数据。
但最后的测试结果居然是slave比master多1行。 说明有一个xa事务在slave上提交了,而没有在master上提交。
通过查看并分析发现slave比master多的这行数据在master上进行提交的时候正好碰到了master 被kill -9,导致该xa事务没有完成,但 这个xa事务已经写完binlog了。。。
这应该就是mysql为什么对xa recover出来的xa 事务提交时不记录binlog的原因,怕重复记录!
但这就很难保证master和slave的数据一致性了,因为故障的时候slave得到的binlog上的事务可能在master上还没提交。
特别是如果主从一致的策略是丢弃master故障时未同步到slave上的事务时,当master恢复的时候应该进行xa commit还是xa rollback需要先去 slave上查看下该xa事务的binlog是否已经同步过来了。
转载请注明转自高孝鑫的博客