XA事务支持仅限于 InnoDB
存储引擎。
对于 “外部XA”, MySQL 服务器充当资源管理器,而客户端程序充当事务管理器。对于 “内部XA”, MySQL 服务器中的存储引擎充当资源管理器,而服务器本身充当事务管理器。内部XA支持受到单个存储引擎的能力限制。内部XA需要处理涉及多个存储引擎的XA事务。内部XA的实现需要存储引擎在表处理程序级别支持两阶段提交,目前只有 InnoDB
满足这个要求。
对于 XA START
,JOIN
和 RESUME
子句被识别,但没有效果。
对于 XA END
,SUSPEND [FOR MIGRATE]
子句被识别,但没有效果。
要求 bqual
部分的 xid
值在每个XA事务中不同,这是当前MySQL XA实现的限制,而不是XA规范的一部分。
XA事务被写入二进制日志中两个部分。当 XA PREPARE
被发出时,事务的第一部分直到 XA PREPARE
被写入使用初始GTID。一个 XA_prepare_log_event
用于标识二进制日志中的这些事务。当 XA COMMIT
或 XA ROLLBACK
被发出时,事务的第二部分仅包含 XA COMMIT
或 XA ROLLBACK
语句被写入使用第二个GTID。注意,事务的初始部分,标识为 XA_prepare_log_event
,不一定跟随其 XA COMMIT
或 XA ROLLBACK
,这可能会导致两个XA事务的二进制日志交叉记录。两个事务部分甚至可能出现在不同的二进制日志文件中。这意味着XA事务在 PREPARED
状态下是持久的,直到明确的 XA COMMIT
或 XA ROLLBACK
语句被发出,以确保XA事务与复制兼容。
在副本上,XA事务准备好后,它将从复制应用程序线程中分离出来,可以由副本上的任何线程提交或回滚。这意味着同一个XA事务可以在 events_transactions_current
表中以不同的状态出现在不同的线程上。events_transactions_current
表显示当前监控事务事件的最新状态,并且在线程空闲时不会更新该状态。因此,XA事务仍然可以在 PREPARED
状态下显示在原始应用程序线程上,尽管它已经被另一个线程处理。要确定仍然需要恢复的XA事务,请使用 XA RECOVER
语句,而不是性能模式事务表。
以下限制适用于使用XA事务:
-
不支持使用复制过滤器或二进制日志过滤器与XA事务的组合。表的过滤可能会导致XA事务在副本上为空,而空XA事务不受支持。此外,使用
InnoDB
表(默认)存储副本的连接元数据存储库和应用程序元数据存储库,XA事务的内部状态将在过滤后的XA事务后更改,并可能与复制事务上下文状态不一致。错误
ER_XA_REPLICATION_FILTERS
将在XA事务受到复制过滤器影响时记录, 无论事务是否为空。如果事务不为空,副本可以继续运行,但您应该采取措施停止使用复制过滤器与XA事务,以避免潜在的问题。如果事务为空,副本将停止。在这种情况下,副本可能处于不确定状态,复制过程的一致性可能会被破坏。特别是,副本上的gtid_executed
集合可能与源上的集合不一致。要解决这种情况,请隔离源并停止所有复制,然后检查复制拓扑结构中的GTID一致性。撤销生成错误消息的XA事务,然后重新启动复制。 -
XA事务被认为不适合基于语句的复制。如果两个XA事务在源上并行提交,并在副本上以逆序准备,锁定依赖关系可能会出现无法安全解决的死锁,复制可能会在副本上失败。当
binlog_format=STATEMENT
时,对于XA事务中的DML语句将发出警告。当binlog_format=MIXED
或binlog_format=ROW
时,XA事务中的DML语句将使用基于行的复制记录,潜在的问题将不存在。 -
您应该注意,当使用相同的事务XID顺序执行XA事务并在
XA COMMIT ... ONE PHASE
处理期间出现中断时,可能无法再同步二进制日志和存储引擎之间的状态。这可能发生在事务已经在存储引擎中准备好,而XA COMMIT语句仍在执行时。这是一个已知的问题。