13.3.7.3 XATransaction 限制
XA 事务支持仅限于InnoDB
存储引擎。
对于“外部 XA”,MySQL 服务器充当资源 Management 器,而 Client 端程序充当事务 Management 器。对于“内部 XA”,MySQL 服务器中的存储引擎充当 RM,而服务器本身充当 TM。内部 XA 支持受单个存储引擎功能的限制。需要内部 XA 来处理涉及多个存储引擎的 XA 事务。内部 XA 的实现要求存储引擎在 table 处理程序级别支持两阶段提交,并且当前仅对InnoDB
如此。
对于XA START,可以识别JOIN
和RESUME
子句,但无效。
对于XA END,可以识别SUSPEND [FOR MIGRATE]
子句,但无效。
对于全局事务中的每个 XA 事务,* xid
值的 bqual
*部分必须不同,这一要求是当前 MySQL XA 实现的限制。它不是 XA 规范的一部分。
在 MySQL 5.7.7 之前,XA 事务与复制不兼容。这是因为处于_状态的 XA 事务将在干净服务器关闭或 Client 端断开连接时回滚。类似地,如果服务器异常关闭然后再次启动,则处于PREPARED
状态的 XA 事务仍将处于PREPARED
状态,但是该事务的内容无法写入二进制日志。在这两种情况下,都无法正确复制 XA 事务。
在 MySQL 5.7.7 和更高版本中,行为有所变化,并且 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_currenttable 中。 events_transactions_currenttable 显示线程上最近监视的事务事件的当前状态,并且在线程空闲时不更新此状态。因此,XA 事务在被另一个线程处理后,仍可以在原始应用程序线程的PREPARED
状态下显示。为了肯定地标识仍处于PREPARED
状态且需要恢复的 XA 事务,请使用XA RECOVER语句而不是 Performance Schema 事务 table。
在 MySQL 5.7.7 和更高版本中使用 XA 事务存在以下限制:
-
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
)之后发生意外的停止,则服务器和二进制日志将被正确恢复并进入一致状态。 -
不支持将复制过滤器或二进制日志过滤器与 XA 事务结合使用。table 的筛选可能会导致 XA 事务在复制从属服务器上为空,并且不支持空的 XA 事务。同样,使用复制从属服务器上的设置master_info_repository=TABLE和relay_log_info_repository=TABLE(在 MySQL 8.0 中成为默认设置),在过滤 XA 事务后,数据引擎事务的内部状态会更改,并且可能与复制事务上下文状态不一致。
每当 XA 事务受到复制过滤器的影响时,无论该事务是否为空,都会记录错误ER_XA_REPLICATION_FILTERS。如果事务不为空,则复制从属服务器可以 continue 运行,但是您应该采取步骤中止对 XA 事务使用复制筛选器,以避免潜在的问题。如果事务为空,则复制从站停止。在这种情况下,复制从设备可能处于不确定状态,在该状态下复制过程的一致性可能会受到影响。特别是,从站的从站上的gtid_executed
设置可能与主站上的gtid_executed
不一致。要解决这种情况,请隔离主服务器并停止所有复制,然后检查整个复制拓扑中的 GTID 一致性。撤消生成错误消息的 XA 事务,然后重新启动复制。
-
在 MySQL 5.7.19 之前,带读取锁的平桌子与 XA 事务不兼容。
-
对于基于语句的复制,XA 事务被认为是不安全的。如果正在从服务器上以相反的 Sequences 准备在主服务器上并行提交的两个 XA 事务,则会发生无法安全解决的锁定依赖关系,并且复制可能会因从服务器上的死锁而失败。对于单线程或多线程复制从属,可能会发生这种情况。设置binlog_format=STATEMENT时,将对 XA 事务中的 DML 语句发出警告。设置binlog_format=MIXED或binlog_format=ROW时,将使用基于行的复制来记录 XA 事务中的 DML 语句,并且不存在潜在的问题。