<a href="http://www.linuxidc.com/Linux/2015-11/124942.htm" target="_blank">http://www.linuxidc.com/Linux/2015-11/124942.htm</a>
XA 将事務的送出分為兩個階段,而這種實作,解決了 binlog 和 redo log的一緻性問題,這就是MySQL内部XA的第三種功能。
MySQL為了相容其它非事物引擎的複制,在server層面引入了 binlog, 它可以記錄所有引擎中的修改操作,因而可以對所有的引擎使用複制功能;MySQL在4.x 的時候放棄redo的複制政策而引入binlog的複制(淘寶丁奇)。
但是引入了binlog,會導緻一個問題——binlog和redo log的一緻性問題:一個事務的送出必須寫redo log和binlog,那麼二者如何協調一緻呢?事務的送出以哪一個log為标準?如何判斷事務送出?事務崩潰恢複如何進行?
MySQL通過兩階段送出(内部XA的兩階段送出)很好地解決了這一問題:
第一階段:InnoDB prepare,持有prepare_commit_mutex,并且write/sync redo log; 将復原段設定為Prepared狀态,binlog不作任何操作;
第二階段:包含兩步,1> write/sync Binlog; 2> InnoDB commit (寫入COMMIT标記後釋放prepare_commit_mutex);
以 binlog 的寫入與否作為事務送出成功與否的标志,innodb commit标志并不是事務成功與否的标志。
因為此時的事務崩潰恢複過程如下:
1> 崩潰恢複時,掃描最後一個Binlog檔案,提取其中的xid;
2> InnoDB維持了狀态為Prepare的事務連結清單,将這些事務的xid和Binlog中記錄的xid做比較,如果在Binlog中存在,則送出,否則復原事務。
通過這種方式,可以讓InnoDB和Binlog中的事務狀态保持一緻。如果在寫入innodb commit标志時崩潰,則恢複時,會重新對commit标志進行寫入;
在prepare階段崩潰,則會復原,在write/sync binlog階段崩潰,也會復原。這種事務送出的實作是MySQL5.6之前的實作。
本文轉自 lirulei90 51CTO部落格,原文連結:http://blog.51cto.com/lee90/1969913,如需轉載請自行聯系原作者