说下 MySQL 内部的 XA 分布式事务?

#每天一道面试题# 42

#悟空拧螺丝# 2021-08-23

XA是X/Open DTP组织(X/Open DTP group)定义的两阶段提交协议。

MySQL本身的插件式架构导致在其内部需要使用XA事务,此时MySQL即是协调者,也是参与者。内部XA事务发生在存储引擎与插件之间或者存储引擎与存储引擎之间。例如,不同的存储引擎之间是完全独立的,因此当一个事务涉及两个不同的存储引擎时,就必须使用内部XA事务。由于只在单机上工作,所以被称为内部XA。

最为常见的内部XA事务存在于二进制日志(Binlog)和InnoDB存储引擎之间。由于复制的需要,因此,目前绝大多数的数据库都开启了Binlog功能。

在事务提交时,先写二进制日志,再写InnoDB存储引擎的重做日志。对上述两个操作的要求也是原子的,即二进制日志和重做日志必须同时写入。若二进制日志先写了,而在写入InnoDB存储引擎时发生了宕机,那么Slave可能会接收到Master传过去的二进制日志并执行,最终导致了主从不一致的情况发生。

为了解决这个问题,MySQL数据库在Binlog与InnoDB存储引擎之间采用XA事务。当事务提交时,InnoDB存储引擎会先做一个PREPARE操作,将事务的Xid写入,接着进行Binlog的写入。如果在Binlog存储引擎提交前,MYSQL数据库宕机了,那么MySQL数据库在重启后会先检查准备的UXID事务是否已经提交,若没有,则在存储引擎层再进行一次提交操作。

二十、说下 MySQL 的外部 XA 事务?

#每天一道面试题# 43 #悟空拧螺丝# 2021-08-24

(1)XA 事务是什么

XA是X/Open DTP组织(X/Open DTP group)定义的两阶段提交协议。

分布式事务通常采用 2PC 协议,全称 Two Phase Commitment Protocol(两阶段提交协议)。该协议主要为了解决在分布式数据库场景下,所有节点间数据一致性的问题。分布式事务通过2PC协议将提交分成两个阶段:

阶段一为准备(prepare)阶段。即所有的参与者准备执行事务并锁住需要的资源。参与者 ready 时,向transaction manager 报告已准备就绪。

阶段二为提交阶段(commit)。当 transaction manager 确认所有参与者都 ready 后,向所有参与者发送 commit命令。

缺点:第一个阶段会锁定资源,等待其他参与者 Ready,在高并发场景下,会严重影响系统的吞吐量。

(2)MySQL 的外部 XA

MySQL在执行分布式事务(外部XA)的时候,MySQL服务器相当于XA“事务资源管理器”,

与MySQL连接的客户端相当于“事务管理器”,比如 Java 应用程序。

事务管理器负责协调多个数据库的事务,先问问各个数据库准备好了吗?如果准备好了,则在数据库执行操作,如果任一数据库没有准备,则回滚事务。

MySQL支持 XASTART/END/PREPARE/COMMIT 这些SQL语句,通过使用这些命令可以完成分布式事务的状态转移。

内部XA事务用于同一实例下跨多引擎事务,而外部XA事务用于跨多 MySQL 实例的分布式事务,需要应用层作为协调者。应用层负责决定提交还是回滚。

内部 XA 事务在昨天发的题目中有解答。