XA 是 X/Open 組織定義的分布式事務規範,定義了事務管理器(TM)與資源管理器(RM)的接口。通過兩階段提交實現多資源的原子性:
prepare 請求commit,RM 將狀態改為「提交完成」rollback,所有 RM 回滾MySQL 官方文檔明確:僅 InnoDB 支持 XA,且分布式事務必須使用 SERIALIZABLE 隔離級別(非分布式事務 REPEATABLE READ 即可)。
XA START 'xid'、XA END 'xid'、XA PREPARE 'xid'、XA COMMIT/ROLLBACK 'xid'MySQL 4.x 放棄 redo log 復制,引入 binlog 兼容非事務引擎。但引入 binlog 導致新問題:事務提交需同時寫 redo log 和 binlog,誰為準?如何協調?崩潰如何恢復?
Phase 1 (Prepare):
InnoDB prepare -> 持有 prepare_commit_mutex -> write/sync redo log
設置回滾段為 Prepared 狀態,binlog 不動作
Phase 2 (Commit):
1. write/sync Binlog
2. InnoDB commit (寫 COMMIT 標記,釋放 prepare_commit_mutex)
關鍵點:以 binlog 寫入成敗 作為事務提交成功與否標準。崩潰恢復邏輯:
缺陷:sync_binlog=1 時,Phase 2 串行化,持有全局大鎖 prepare_commit_mutex,性能急劇下降。
將 Phase 2 拆分為三個階段,各階段由一個線程串行處理,但階段間可並行:
fsync(多線程合併寫入磁盤,核心優化)優勢:三階段流水線並行,大幅提升吞吐。Prepare 階段未變(仍 write/sync redo log)。
延伸:5.7 引入 MTS(多線程 Slave 復制),利用組提交時的 seqno 實現從庫並行回放。
淘寶優化邏輯(官方 5.7.6 合入):
Step 1. InnoDB Prepare,記錄當前 LSN 到 THD
Step 2. 進入 Flush 階段,Leader 收集隊列,計算最大 LSN
Step 3. 將 InnoDB redo log write/fsync 到指定 LSN(隱式 redo log 組寫入)
Step 4. 寫 Binlog 及後續工作 (sync Binlog, InnoDB commit)
核心思想:將 redo log write/sync 延遲到 Binlog 組提交的 Flush 階段之後、Sync Binlog 之前。顯式實現 redo log 組寫入,減少 log_sys->mutex 競爭。Binlog 與 Redo Log 雙雙組提交優化。
官方 Release Note:When using InnoDB with binary logging enabled, concurrent transactions written in the InnoDB redo log are now grouped together before synchronizing to disk when innodb_flush_log_at_trx_commit is set to 1, which reduces the amount of synchronization operations. This can lead to improved performance.
innodb_support_xaCommand-Line Format: --innodb_support_xa
Scope: Global, Session
Dynamic: Yes
Type: Boolean
Default: TRUE
log_bin 且多線程並發寫入生產建議:主庫永不關閉;從庫若為只讀單線程回放可關閉提升性能。