前言
Undo log
是InnoDB MVCC
事務特性的重要組成部分
,同時可以提供數據回滾
。當我們對記錄做了變更操作
時就會產生undo記錄
,Undo記錄默認被記錄到系統表空間(ibdata)中,但從5.6
開始,也可以使用獨立的Undo 表空間
。
Undo記錄中存儲的是老版本數據
,當一個舊的事務
需要讀取數據
時,爲了能讀取到老版本的數據,需要順着undo鏈
找到滿足其可見性的記錄
。當版本鏈很長時,通常可以認爲這是個比較耗時的操作(例如bug#69812)。如果因爲某些原因導致事務失敗或回滾
了,可以藉助
該undo進行回滾
。
大多數對數據的變更操作
包括INSERT/DELETE/UPDATE
,其中INSERT
操作在事務提交前只對當前事務可見,因此產生的Undo日誌可以在事務提交後直接刪除
(誰會對剛插入的數據有可見性需求呢!!),而對於UPDATE/DELETE
則需要維護多版本
信息,在InnoDB裏,UPDATE和DELETE操作產生的Undo日誌被歸成一類,即update_undo
。
本文是對整個Undo生命週期過程的闡述,代碼分析基於當前最新的MySQL5.7版本。
Undo Log
undo log和redo log記錄物理日誌
不一樣,它是邏輯日誌
。可以認爲當delete
一條記錄時,undo log中會記錄一條對應的insert
記錄,反之亦然,當update
一條記錄時,它記錄一條對應相反的update
記錄。當執行rollback時,就可以從undo log中的邏輯記錄讀取到相應
的內容並進行回滾
。有時候應用到行版本控制
的時候,也是通過undo log來實現的:當讀取的某一行被其他事務鎖定時,它可以從undo log中分析出該行記錄的歷史數據
是什麼,讓用戶實現非鎖定一致性
讀取。
爲了保證事務併發操作時,在寫各自的undo log時不產生衝突,InnoDB採用回滾段
的方式來維護undo log的併發寫入和持久化。回滾段實際上是一種 Undo 文件組織方式
,每個回滾段
由1024
個undo log slot
組成。每個undo操作
在記錄的時候佔用一個undo log slot
。另外,undo log也會產生redo log
,因爲undo log也要實現持久性
保護。
存儲
MySQL5.5以後可以支持128個rollback segment,即支持128*1024個undo操作,還可以通過變量innodb_undo_logs
(5.6版本以前該變量是 innodb_rollback_segments )自定義
多少個rollback segment
,默認值爲128
。undo log默認存放
在共享表空間
中。如果開啓了innodb_file_per_table
,將放在每個表的.ibd
文件中。
在MySQL5.6中,undo的存放位置還可以通過變量 innodb_undo_directory
來自定義存放目錄
,默認值爲"."表示datadir。
默認rollback segment全部寫在一個文件中,但可以通過設置變量 innodb_undo_tablespaces
平均分配到多少個文件中。該變量默認值爲0
,即全部寫入一個表空間文件
。該變量爲靜態變量,只能在數據庫示例停止狀態下修改,如寫入配置文件或啓動時帶上對應參數。但是innodb存儲引擎在啓動過程中提示,不建議修改爲非0
的值
delete/update操作的內部機制
當事務提交
的時候,innodb不會立即刪除
undo log,因爲後續
還可能會用到undo log,如隔離級別爲repeatable read
時,事務讀取
的都是開啓事務時
的最新提交行版本
,只要該事務不結束
,該行版本就不能刪除
,即undo log不能刪除。
但是在事務提交
的時候,會將該事務對應的undo log放入到刪除列表
中,未來通過purge來刪除
。並且提交事務時,還會判斷undo log分配的頁是否可以重用
,如果可以重用,則會分配給後面來的事務,避免
爲每個獨立的事務分配獨立的undo log頁
而浪費存儲空間和性能
。
通過undo log記錄delete和update操作的結果發現:(insert操作無需分析,就是插入行而已)
delete
操作實際上不會直接刪除
,而是將delete對象打上delete flag
,標記爲刪除,最終
的刪除操作是purge
線程完成的。update
分爲兩種
情況:update的列是否是主鍵列
。- 如果
不是主鍵列
,在undo log中直接反向記錄
是如何update
的。即update是直接進行的。 - 如果
是主鍵列
,update分兩部執行:先刪除
該行,再插入
一行目標行。
- 如果
參考undo數據結構:http://mysql.taobao.org/monthly/2015/04/01/
本文參考:https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html