当 MySQL 执行 XA 事务时遭遇崩溃,且看华为云如何保障数据一致性
摘要:当前 MySQL 所有版本不支持分布式事务的崩溃恢复安全,这严重影响了分布式事务的高可用保障。
华为云数据库内核高级技术专家,拥有十多年 MySQL 内核研发经验,目前在华为云数据库团队研发华为云数据库(RDS for MySQL 和 GaussDB(for MySQL))内核特性和服务化特性,修复华为云数据库现网问题;曾在官方 MySQL 团队研发 MySQL 内核特性和修复 MySQL 内核问题九年多,尤其擅长 MySQL Replication。
注:本文如没有特殊说明,MySQL 指社区版 MySQL;binlog 指 MySQL server 日志;redo Log 指 MySQL InnoDB 日志
MySQL replication 实时同步主库上执行的事务到备库,并且支持一般事务的崩溃恢复安全,这为一般事务的高可用提供了坚实的保障。如果没有此高可用保障,主库崩溃(不能正常恢复场景)后,数据库服务轻则中断几十分钟甚至几小时,重则丢失用户数据。
但是当前 MySQL 所有版本不支持分布式事务的崩溃恢复安全,这严重影响了分布式事务的高可用保障。华为云数据库(包括 RDS (for MySQL) 和 GaussDB (for MySQL))解决了这一痛点,支持分布式事务的崩溃恢复安全,极大地提升华为云数据库的可靠性和可用性。
接下来我们将逐个讨论 MySQL 在分布式事务崩溃恢复安全方面的几个常见问题,以及华为云数据库采取了什么解决方案来保证数据的一致性。
(如需了解分布式事务,请参考这里:https://dev.mysql.com/doc/refman/8.0/en/xa.html)
问题一:
如上图所示:如果崩溃发生在危险区间段内的任意一点,主库重启后,binlog 中保存有准备阶段执行的事务,但是 InnoDB 回滚了准备阶段执行的事务。从而导致 MySQL server 和 InnoDB 数据不一致。准备阶段执行的事务会被回放到备库,它获得的所有事务处理过程中使用的锁永远不能被释放。最终导致备库回放需要获得相关锁的其它事务时锁超时失败,复制中断。
华为云数据库解决方案
如上图流程所示:
如果崩溃发生在阶段一,主库重启后,这个分布式事务准备阶段既不在 MySQL server 中,也不在 InnoDB 中;
如果崩溃发生在阶段二,主库重启恢复过程中这个分布式事务准备阶段会被 InnoDB 回滚掉,最终这个分布式事务准备阶段既不在 MySQL server 中,也不在 InnoDB;
如果崩溃发生在阶段三,主库重启后,这个分布式事务准备阶段既存在 MySQL server 中,也存在 InnoDB 中;
所以,无论崩溃发生在上图中的哪一点,主库重启后,华为云数据库都能保证 MySQL server 和 InnoDB 数据的一致性。
问题二:
如上图所示:如果崩溃发生在危险区间段内的任意一点,主库重启后,binlog 保存有 XA COMMIT xid, 但是 MySQL InnoDB 没有提交这个分布式事务。
如果不重新提交,那么在准备阶段获得的所有事务处理过程中使用的锁永远不能被释放,最终导致主库执行需要获得相关锁的其它事务时锁超时失败;
如果重新提交,XA COMMIT xid 再次被持久化到 binlog,备库在回放第二个 XA COMMIT xid 时抛出“Unknown XID”错误,导致复制中断。
华为云数据库解决方案
主库在重启的过程中以 binlog 作为仲裁提交了这个分布式事务准备阶段执行的事务,保证了华为云数据库 MySQL server 和 MySQL InnoDB 数据的一致性。
问题三:
如上图所示:如果崩溃发生在危险区间段内的任意一点,主库重启后, binlog 保存有 XA ROLLBACK xid,但是 MySQL InnoDB 没有回滚这个分布式事务。
如果不重新回滚,这个分布式事务准备阶段获得的所有事务处理过程中使用的锁永远不能被释放,最终导致主库执行需要获得相关锁的其它事务时锁超时失败;
如果重新回滚,XA ROLLBACK xid 再次被持久化到 binlog,备库在回放第二个 XA ROLLBACK xid 时抛出“Unknown XID”错误,导致复制中断。
华为云数据库解决方案
主库在重启的过程中以 binlog 作为仲裁回滚了这个分布式事务准备阶段执行的事务,保证了华为云数据库 MySQL server 和 MySQL InnoDB 数据的一致性。
问题四:
如上图所示:如果崩溃发生在危险区间段内的任意一点,主库重启后,binlog 中保存有一阶段提交分布式事务,但是 MySQL InnoDB 回滚了这个一阶段提交分布式事务。从而导致 MySQL server 和 MySQL InnoDB 数据不一致。一阶段提交的分布式事务会被回放到备库,最终导致备库数据和主库数据的不一致。
华为云数据库解决方案
如上图所示:
如果崩溃发生在阶段一,主库重启后,这个一阶段提交分布式事务既不在 MySQL server 中,也不在 MySQL InnoDB 中;
如果崩溃发生在阶段二,主库重启恢复过程中这个一阶段提交分布式事务会被 MySQL InnoDB 回滚掉,最终这个分布式事务既不在 MySQL server 中,也不在 MySQL InnoDB 中;
如果崩溃发生在阶段三,主库重启后,这个一阶段提交分布式事务既存在 MySQL server 中,也存在 MySQL InnoDB 中;
无论崩溃发生在上图中的哪一点,主库重启后,华为云数据库都能保证 MySQL server 和 MySQL InnoDB 数据的一致性。
华为云数据库很好地解决了分布式事务崩溃恢复安全的相关问题,极大地提升数据库的可靠性和可用性,提升了用户使用华为云数据库的体验。后续我们会持续在分布式事务方面做更多的优化和解决 MySQL 可能遇到的问题,也欢迎大家使用华为云数据库分布式事务,体验华为云数据库卓越的可靠性和可用性,期待您的反馈!https://www.huaweicloud.com/product/gaussdb_mysql.html
版权声明: 本文为 InfoQ 作者【华为云开发者社区】的原创文章。
原文链接:【http://xie.infoq.cn/article/87e9541844226b3ca8595880b】。文章转载请联系作者。
评论