天天看點

MySQL的内部XA事務

<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&gt; write/sync Binlog; 2&gt; InnoDB commit (寫入COMMIT标記後釋放prepare_commit_mutex);

以 binlog 的寫入與否作為事務送出成功與否的标志,innodb commit标志并不是事務成功與否的标志。

因為此時的事務崩潰恢複過程如下:

1&gt; 崩潰恢複時,掃描最後一個Binlog檔案,提取其中的xid; 

2&gt; 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,如需轉載請自行聯系原作者

繼續閱讀