15.3.8.3 XA 事务限制
XA 事务支持仅限于InnoDB
存储引擎。
对于“外部XA,”MySQL 服务器作为资源管理器,客户端程序作为事务管理器。对于“内部XA”,存储引擎内的 MySQL 服务器作为 RM,服务器本身作为 TM。内部XA 的支持受到个别存储引擎的能力限制。内部XA 需要存储引擎支持在表处理器级别的两阶段提交,当前只有InnoDB
支持。
对于XA START
,JOIN
和 RESUME
take no effect。
对于XA END
,SUSPEND [FOR MIGRATE]
take no effect。
当前 MySQL XA 实现的限制之一是,XA 事务中的bqual
部分的xid
值必须在全局事务中不同。这个限制不属于 XA 规范。
XA 事务将被写入二进制日志中两部分。对于XA PREPARE
,事务的前半部分到XA PREPARE
将被写入使用初始 GTID。使用XA_prepare_log_event
来标识在二进制日志中的事务。对于XA COMMIT
或 XA ROLLBACK
,事务的后半部分,包含仅XA COMMIT
或 XA ROLLBACK
语句,将被写入使用第二个 GTID。注意,事务的前半部分,标识为XA_prepare_log_event
,不一定会被其XA COMMIT
或 XA ROLLBACK
语句所跟随,可以导致二进制日志中的事务交错。事务的前半部分和后半部分甚至可能出现在不同的二进制日志文件中。这意味着在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事务而改变,并且可能与复制事务上下文状态不一致。错误
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语句将使用行级别复制,潜在问题将不存在。 -
您应该注意,在使用同一个事务XID执行XA事务序列时,如果在处理
XA COMMIT ... ONE PHASE
时出现中断,可能无法将binary log和存储引擎的状态同步。这可能发生在事务已经在存储引擎中准备好,而XA COMMIT
语句仍在执行时。这是一个已知问题。