XA 事务支持仅限于
InnoDB
存储引擎。
对于“外部 XA ”,MySQL 服务器充当资源管理器,客户端程序充当事务管理器。对于“内部 XA ”,MySQL 服务器中的存储引擎充当 RM,而服务器本身充当 TM。内部 XA 支持受限于各个存储引擎的能力。处理涉及多个存储引擎的 XA 事务需要内部 XA。内部 XA 的实现要求存储引擎在表处理程序级别支持两阶段提交,目前仅适用于InnoDB
.
对于XA
START
,JOIN
和
RESUME
子句被识别但没有效果。
因为XA
END
该SUSPEND [FOR MIGRATE]
条款被承认但没有效力。
全局事务中每个 XA 事务的bqual
部分值都不同
的要求是当前 MySQL XA 实现的限制。xid
它不是 XA 规范的一部分。
XA 事务分两部分写入二进制日志。发出时XA PREPARE
,事务的第一部分XA PREPARE
使用初始 GTID 写入。AXA_prepare_log_event
用于标识二进制日志中的此类事务。当
发出XA COMMIT
orXA ROLLBACK
时,事务的第二部分仅包含
XA COMMIT
orXA ROLLBACK
语句,使用第二个 GTID 编写。请注意,由 标识的交易的初始部分
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
表显示线程上最近监视的事务事件的当前状态,并且在线程空闲时不更新此状态。PREPARED
所以 XA 事务在被另一个线程处理后,仍然可以显示为原始应用程序线程的状态。积极识别仍在的 XA 事务PREPARED
state 并且需要恢复,使用XA
RECOVER
语句而不是 Performance Schema 事务表。
使用 XA 事务存在以下限制:
在 MySQL 8.0.30 之前,XA 事务对于二进制日志的意外停止没有完全的弹性。如果服务器在执行
XA PREPARE
,XA COMMIT
,XA ROLLBACK
, 或XA COMMIT ... ONE PHASE
语句的过程中意外停止,服务器可能无法恢复到正确的状态,从而使服务器和二进制日志处于不一致的状态。在这种情况下,二进制日志可能包含未应用的额外 XA 事务,或者遗漏已应用的 XA 事务。此外,如果启用了 GTID,则在恢复后@@GLOBAL.GTID_EXECUTED
可能无法正确描述已应用的交易。XA PREPARE
请注意,如果在 之前、之间XA PREPARE
和XA COMMIT
(或XA ROLLBACK
)或之后XA COMMIT
(或)发生意外停止XA ROLLBACK
,服务器和二进制日志将被正确恢复并进入一致状态。从 MySQL 8.0.30 开始,这不再是问题;服务器实现
XA PREPARE
为两阶段操作,它维护存储引擎和服务器之间准备操作的状态,并强加存储引擎和二进制日志之间的执行顺序,以便在状态一致之前不广播并持久存在于服务器节点上。需要注意的是,当使用同一个事务XID顺序执行XA事务时,在处理过程中出现中断
XA COMMIT ... ONE PHASE
,可能无法再同步二进制日志和存储引擎的状态。如果在存储引擎中准备好此事务之后发生刚才描述的一系列事件,而XA COMMIT
语句仍在执行,则可能会发生这种情况。这是一个已知的问题。不支持将复制过滤器或二进制日志过滤器与 XA 事务结合使用。过滤表可能会导致副本上的 XA 事务为空,并且不支持空的 XA 事务。此外,副本的连接元数据存储库和应用程序元数据存储库存储在
InnoDB
表中,这成为 MySQL 8.0 中的默认设置,数据引擎事务的内部状态在过滤后的 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 语句使用基于行的复制进行记录,并且不存在潜在问题。
在 MySQL 5.7.7 之前,XA 事务与复制根本不兼容。这是因为处于PREPARED
状态的 XA 事务将在干净的服务器关闭或客户端断开连接时回滚。同理,一个处于状态的XA事务,在服务器异常关闭再启动的情况下,PREPARED
状态仍然存在PREPARED
,但是事务的内容无法写入二进制日志。在这两种情况下,都无法正确复制 XA 事务。