13.3.7.3 XATransaction 限制

XA 事务支持仅限于InnoDB存储引擎。

对于“外部 XA”,MySQL 服务器充当资源 Management 器,而 Client 端程序充当事务 Management 器。对于“内部 XA”,MySQL 服务器中的存储引擎充当 RM,而服务器本身充当 TM。内部 XA 支持受单个存储引擎功能的限制。需要内部 XA 来处理涉及多个存储引擎的 XA 事务。内部 XA 的实现要求存储引擎在 table 处理程序级别支持两阶段提交,并且当前仅对InnoDB如此。

对于XA START,可以识别JOINRESUME子句,但无效。

对于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 COMMITXA ROLLBACK时,使用第二个 GTID 写入仅包含XA COMMITXA ROLLBACK语句的事务的第二部分。请注意,由XA_prepare_log_event标识的事务的初始部分不必紧跟其XA COMMITXA ROLLBACK,这会导致任何两个 XA 事务的交错二进制日志记录。 XA 事务的两个部分甚至可以出现在不同的二进制日志文件中。这意味着处于PREPARED状态的 XA 事务现在将一直保留,直到发出明确的XA COMMITXA 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 PREPAREXA COMMITXA ROLLBACKXA COMMIT ... ONE PHASE语句的过程中意外中断,则服务器可能无法恢复到正确的状态,从而使服务器和二进制日志处于不一致的状态。在这种情况下,二进制日志可能包含未应用的额外 XA 事务,或者错过了已应用的 XA 事务。另外,如果启用了 GTID,则恢复@@GLOBAL.GTID_EXECUTED后可能无法正确描述已应用的事务。请注意,如果在XA PREPARE之前,XA PREPAREXA COMMIT(或XA ROLLBACK)之间或XA COMMIT(或XA ROLLBACK)之后发生意外的停止,则服务器和二进制日志将被正确恢复并进入一致状态。

  • 不支持将复制过滤器或二进制日志过滤器与 XA 事务结合使用。table 的筛选可能会导致 XA 事务在复制从属服务器上为空,并且不支持空的 XA 事务。同样,使用复制从属服务器上的设置master_info_repository=TABLErelay_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=MIXEDbinlog_format=ROW时,将使用基于行的复制来记录 XA 事务中的 DML 语句,并且不存在潜在的问题。