文档首页
MySQL 9.0 参考手册
相关文档 下载本手册

MySQL 9.0 参考手册  /  ...  /  XA 事务的限制

15.3.8.3 XA 事务的限制

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

对于 外部 XA,MySQL 服务器充当资源管理器,而客户端程序充当事务管理器。对于 内部 XA,MySQL 服务器内的存储引擎充当 RM,而服务器本身充当 TM。内部 XA 支持受各个存储引擎功能的限制。内部 XA 是处理涉及多个存储引擎的 XA 事务所必需的。内部 XA 的实现要求存储引擎在表处理程序级别支持两阶段提交,目前只有 InnoDB 支持此功能。

对于 XA STARTJOINRESUME 子句被识别,但没有效果。

对于 XA ENDSUSPEND [FOR MIGRATE] 子句被识别,但没有效果。

要求 bqual 部分的 xid 值在全局事务中的每个 XA 事务中都不同,这是当前 MySQL XA 实现的限制。它不是 XA 规范的一部分。

XA 事务被写入二进制日志分为两个部分。当发出 XA PREPARE 命令时,事务的第一部分(直到 XA PREPARE)使用初始 GTID 写入。一个 XA_prepare_log_event 用于在二进制日志中识别此类事务。当发出 XA COMMITXA ROLLBACK 命令时,事务的第二部分,只包含 XA COMMITXA ROLLBACK 语句,使用第二个 GTID 写入。请注意,由 XA_prepare_log_event 标识的事务的第一部分并不一定后面紧跟着其 XA COMMITXA ROLLBACK,这会导致任何两个 XA 事务的二进制日志交错记录。XA 事务的两个部分甚至可能出现在不同的二进制日志文件中。这意味着处于 PREPARED 状态的 XA 事务现在是持久化的,直到发出显式的 XA COMMITXA ROLLBACK 语句,确保 XA 事务与复制兼容。

在副本上,XA 事务被准备后立即与复制应用线程分离,并且可以在副本上的任何线程上提交或回滚。这意味着同一个 XA 事务可能在 events_transactions_current 表中以不同的状态出现在不同的线程上。 events_transactions_current 表显示线程上最近监控到的事务事件的当前状态,并且不会在线程处于空闲状态时更新此状态。因此,XA 事务仍可能在原始应用线程中显示为 PREPARED 状态,即使它已被另一个线程处理过。要积极地识别仍然处于 PREPARED 状态且需要恢复的 XA 事务,请使用 XA RECOVER 语句,而不是 Performance Schema 事务表。

使用 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=MIXEDbinlog_format=ROW 时,XA 事务内的 DML 语句使用基于行的复制记录,并且潜在问题不存在。

  • 您应该注意,当使用相同的事务 XID 依次执行 XA 事务,并在处理 XA COMMIT ... ONE PHASE 期间发生中断时,可能无法再同步二进制日志和存储引擎之间的状态。如果上述一系列事件发生在该事务已在存储引擎中准备完毕之后,而 XA COMMIT 语句仍在执行,则可能会发生这种情况。这是一个已知问题。