type
status
date
slug
summary
tags
category
icon
password

簡介

XA Traction 是 MySQL 實現 Two-phase Commit (2PC, 兩階段提交) 的方式,用來實現分佈式 Trancation。
在 XA Trancation 中有兩個角色
  • Resource Manager (RM):負責管理各自的 Transaction,也就是實際負責 prepare 和 commit 的操作,並告訴 RM 結果。
  • Transaction Managers (TM):負責和每個 RM 協調通信,也就是通知 RM 進行 prepare, commit 的操作。
其中在 MySQL 又分為 內部XA外部XA

內部 XA

其實內部 XA 指的就是 binlog 和 redo log 的兩階段提交,其中 InnoDB 引擎擔任 RM,Sever 層擔任 TM
notion image
 

外部 XA

由 Server 端擔任 RM,Client 端擔任 TM
notion image
  1. TM 產生 XID 並告訴 RM 開始 Transaction
  1. RM 各自執行自己的 Transaction
  1. TM 會像 RM 詢問 Transaction 是否已經到了 PREPARE 階段
  1. RM 完成本地的 Transaction 後會對該 XID 執行 XA END & XA PREPARE
  1. 當 TM 確認所有 RM 都 PREPARE 之後,向所有的 RM 發起 COMMIT

限制

  • 在 MySQL 8.0.30 之前,XA 交易在遇到非預期的宕機時,對於二進位日誌(binary log)並不能完全保證恢復正確。
    • 如果伺服器在執行 XA PREPAREXA COMMITXA ROLLBACKXA COMMIT ... ONE PHASE 的過程中發生非預期的中斷,伺服器可能無法恢復到正確狀態,導致伺服器與二進位日誌之間出現不一致的情況。
      在這種情況下,二進位日誌可能會:
    • 包含了尚未真正套用的多餘 XA 交易
    • 遺漏了已經套用的 XA 交易。
    • 此外,如果啟用了 GTID,恢復後 @@GLOBAL.GTID_EXECUTED 可能無法正確描述實際已經套用的交易
       
      從 MySQL 8.0.30 開始,上述問題已經不存在;伺服器將 XA PREPARE 實作為一個「兩階段操作」,這樣可以在 儲存引擎與伺服器之間維持 prepare 狀態,並且在 儲存引擎與 binary log 之間強制執行順序,確保在狀態於伺服器節點上一致且持久化之前,不會被寫入(廣播)到 binary log。
       
      ⚠️ 不過需要注意:
      同一個交易 XID 被用來連續執行多個 XA 交易,並且在執行 XA COMMIT ... ONE PHASE 的過程中發生中斷,可能仍會導致 binary log 與儲存引擎之間的狀態無法同步
      這種情況會發生在以下條件下:
    • 該交易已經在儲存引擎中完成了 prepare
    • 而此時 XA COMMIT 語句仍在執行中。
    • 這是一個 已知問題
  • 不支持 replication filter & binlog filter 和 XA Transaction 一起使用。

參考

MySQL :: MySQL 8.0 Reference Manual :: 15.3.8 XA Transactions
zhuanlan.zhihu.com
www.percona.com