【MySQL】【筆記】MySQL的兩個兩階段
1.事務的兩階段提交
MySQL爲了兼容其他非事務引擎的複製,在server服務層引入了binlog,Binlog負責記錄所有引擎中的修改操作,也因爲如此,binlog相比redo log更全面,更適合作爲複製的媒介使用。
MySQL通過兩階段提交解決了服務層binlog與引擎層Innodb的redo log的一致性與協同問題。
第一階段:InnoDB prepare,持有prepare_commit_mutex,並寫入到redo log中。將回滾段(undo)設置爲Prepared狀態,binlog不做任何操作。
第二階段:將事務寫入Binlog中,將redo log中的對應事務打上commit標記,並釋放prepare_commit_mutex。
MySQL以binlog的寫入與否作爲事務是否成功的標記,innodb引擎的redo commit標記並不是這個事務成功與否的標記。
崩潰時:
掃描最後一個Binlog文件,提取其中所有的xid。
InnoDB維持了狀態爲Prepare的事務鏈表,將這些事務的xid與剛剛提取的xid做比較,若存在,則提交prepare的事務,若不存在,回滾。
2.兩階段的加鎖
在事務中只有提交(commit)或者回滾(rollback)時纔是解鎖階段,
其餘時間爲加鎖階段。
在對記錄更新操作或者(select for update、lock in share model)時,會對記錄加鎖(有共享鎖、排它鎖、意向鎖、gap鎖、nextkey鎖等等)
加鎖階段:只加鎖,不放鎖。解鎖階段:只放鎖,不加鎖。
附:參考文章