XA 事务支持仅限于 InnoDB
存储引擎。
对于““外部 XA”,MySQL 服务器充当资源管理器,客户端程序充当事务管理器。对于““内部 XA”,MySQL 服务器内的存储引擎充当 RM,服务器本身充当 TM。内部 XA 支持受限于各个存储引擎的功能。处理涉及多个存储引擎的 XA 事务需要内部 XA。内部 XA 的实现要求存储引擎在表处理器级别支持两阶段提交,目前只有 InnoDB
符合此要求。
对于 XA START
,JOIN
和 RESUME
子句被识别,但不起作用。
对于 XA END
,SUSPEND [FOR MIGRATE]
子句被识别,但不起作用。
全局事务中每个 XA 事务的 xid
值的 bqual
部分必须不同的要求是当前 MySQL XA 实现的限制。它不是 XA 规范的一部分。
XA 事务分两部分写入二进制日志。当发出 XA PREPARE
时,使用初始 GTID 写入事务的第一部分(直至 XA PREPARE
)。XA_prepare_log_event
用于在二进制日志中标识此类事务。当发出 XA COMMIT
或 XA ROLLBACK
时,使用第二个 GTID 写入事务的第二部分,其中仅包含 XA COMMIT
或 XA ROLLBACK
语句。请注意,由 XA_prepare_log_event
标识的事务的初始部分后面不一定跟着其 XA COMMIT
或 XA ROLLBACK
,这可能导致任何两个 XA 事务的二进制日志交错。XA 事务的两部分甚至可能出现在不同的二进制日志文件中。这意味着处于 PREPARED
状态的 XA 事务现在将一直保持,直到发出显式的 XA COMMIT
或 XA ROLLBACK
语句,从而确保 XA 事务与复制兼容。
在副本上,XA 事务准备就绪后,会立即从复制应用线程分离,并且可以由副本上的任何线程提交或回滚。这意味着同一个 XA 事务可能会在 events_transactions_current
表中针对不同线程显示不同的状态。events_transactions_current
表显示线程上最近监视的事务事件的当前状态,并且在线程空闲时不会更新此状态。因此,在另一个线程处理 XA 事务后,它仍然可以在原始应用线程中显示为 PREPARED
状态。要肯定地标识仍处于 PREPARED
状态且需要恢复的 XA 事务,请使用 XA RECOVER
语句,而不是性能模式事务表。
使用 XA 事务存在以下限制:
不支持将复制过滤器或二进制日志过滤器与 XA 事务结合使用。过滤表可能会导致 XA 事务在副本上为空,并且不支持空 XA 事务。此外,如果副本的连接元数据存储库和应用元数据存储库存储在
InnoDB
表中(默认),则数据引擎事务的内部状态会在过滤的 XA 事务后发生更改,并且可能与复制事务上下文状态不一致。每当 XA 事务受复制过滤器影响时,无论事务是否因此为空,都会记录错误
ER_XA_REPLICATION_FILTERS
。如果事务不为空,则副本可以继续运行,但您应采取措施停止将复制过滤器与 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
语句仍在执行,则可能会发生这种情况。这是一个已知问题。