註:文中有個易混淆的地方"事務" sql事務,即每次資料庫操作生成的事務,這個事務trx_id只在undolog里存儲,同時undolog維護了此事務是否完成的狀態。 日誌持久化事務,為了保證redolog和binlog的一致性而用的Mysql內部獨立維護的2PC提交事務。這個xid只有在redol ...
註:文中有個易混淆的地方"事務"
- sql事務,即每次資料庫操作生成的事務,這個事務trx_id只在undolog里存儲,同時undolog維護了此事務是否完成的狀態。
- 日誌持久化事務,為了保證redolog和binlog的一致性而用的Mysql內部獨立維護的2PC提交事務。這個xid只有在redolog和binlog持久化文件中存儲。
各日誌的存儲內容
閱讀前提:需要對mysql的數據存儲結構有一定瞭解,即數據頁的持久化和記憶體讀取邏輯。
binlog日誌
binlog日誌存儲的是對資料庫實際的數據操作,可以理解為存儲的所有的資料庫更新sql。
mysql預設不開啟binlog,binlog主要用於主從同步和與其他資料庫的數據共用(通過中間件監聽binlog)。
undolog日誌
undolog存儲的是事務的回滾數據,存儲的數據回滾的關鍵信息。undolog數據存儲在undolog表空間中,也是通過數據頁的形式存儲,和普通的數據頁一樣,也會不定期的進行持久化。
undolog也通過頁存儲,有自己獨立的表空間,所以undolog記錄的時候,舊的undolog可能會被覆蓋(當然mysql會保證未提交事務的undolog和用於mvvc的undolog是不會被覆蓋的),同時也會生成相應的redolog。有的人理解為redolog里也存儲了undolog的日誌,其實是不對的,這個日誌只是用來恢復undolog表空間的,並不是undolog實際的日誌。
redolog日誌
redolog存儲的是對頁結構的更新日誌,可以理解為記錄了數據頁里修改了哪幾個位元組。用於mysql崩潰後的數據恢復,數據存儲在ib_logfile中。
redolog中有一個重要參數即checkpoint_lsn記錄了哪些redolog對應的數據頁已經持久化了,是數據恢復的一個非常重要的參數。
同時為了保證數據持久化,事務提交時所有的redolog必須持久化,由於多個事務的redolog是可以穿插寫入的,這就導致有部分未提交的事務被刷盤了。
redolog和binlog的二階段提交
redolog和binlog的二階段提交主要是為了防止系統崩潰時,redolog寫完,binlog沒有寫,導致主從不一致的問題。
innodb維護了一套事務表(註意這裡的事務不是mysql的事務,是redolog持久化的事務),redolog和binlog持久化時會生成一個新的事務,並分配一個xid即2PC事務id給這次持久化操作。
持久化流程
- redolog寫盤並存儲xid
- binlog寫盤並存儲xid,2PC事務標記已提交,redolog事務提交。
崩潰恢復
- 掃描最後一個binlog文件,提取其中的xid;
- InnoDB 維持了狀態為Prepare的事務鏈表,將這些事務的xid和binlog中記錄的xid做比較,如果在binlog中存在則提交,不存在則回滾事務。
數據恢復流程 基於binlog redolog undolog
- 通過binlog的xid和事務鏈表中的事務xid比較,找到不存在的事務的xid,去redolog中把這些事務回滾(刪除)。
- 以checkpoint點的redolog為起點開始恢複數據,即恢覆上圖checkpoint到binlog之間的redolog數據。
- 由於undolog數據頁的修改也記錄在redolog中,未寫盤的undolog數據頁也被恢復。
- 在undolog表空間中查詢未提交的事務(Sql事務)執行undolog日誌進行回滾
- 數據恢復完成
參考資料:《MySQL是怎樣運行的》及其他網路資料