MySQL通過內部XA事務,保持了binlog與redo log之間數據一致性
- 2019 年 10 月 4 日
- 筆記
MySQL通過內部XA事務,保持了binlog與redo log之間數據一致性:
參考:http://www.linuxidc.com/Linux/2015-11/124942.htm
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 redo log prepare,持有prepare_commit_mutex,並且write/sync redo log; 將回滾段設置為Prepared狀態,binlog不作任何操作;
第二階段:包含兩步,1> write/sync Binlog; 2> InnoDB redo log 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之前的實現。