MySQL事務的實現涉及到redo和undo以及purge,redo是保證事務的原子性和持久性;undo是保證事務的一致性(一致性讀和多版本併發控制);purge清理undo表空間背景知識,對於Innodb表中的行每一行包括:6位元組的事務ID(DB_TRX_ID)欄位: 用來標識最近一次對本行記錄做 ...
MySQL事務的實現涉及到redo和undo以及purge,redo是保證事務的原子性和持久性;undo是保證事務的一致性(一致性讀和多版本併發控制);purge清理undo表空間
背景知識,對於Innodb表中的行每一行包括:
6位元組的事務ID(DB_TRX_ID)欄位: 用來標識最近一次對本行記錄做修改(INSERT|UPDATE)的事務的標識符, 即最後一次修改(INSERT|UPDATE)本行記錄的事務id。
7位元組的回滾指針(DB_ROLL_PTR)欄位: 指寫入回滾段(ROLLBACK segment)的 UNDO LOG record (撤銷日誌記錄記錄)。
如果一行記錄被更新, 則 UNDO LOG record 包含 '重建該行記錄被更新之前內容' 所必須的信息。
1,MySQL事務執行過程中,
對於undo log
對於update或者delete操作,每一行都保存了一個事務Id,修改事務Id為當前Session的事務id,
生成數據行事務之前的版本,將當前行的回滾指針指向事務之前的版本。
對於insert操作,將當前行的回滾指針指為空,因為insert沒有事務操作之前的版本。
對於redo log
隨著update\delete\insert操作的執行,重做日誌Redo Log不斷地寫入重做日誌緩存(redo_log_buffer),
對於Redo Log Buffer的落盤(寫入 Redo Log File),有三種策略:
(1),事務commit的時候,
(2),redo_log_buffer(預設8MB)使用超過50%的時候,
(3),發生checkpoint的時候
也就是說,Redo Log Buffe的落盤並不一定是事務提交的時候才寫入的,對於大事務,redo log是有可能逐步落盤的(2,3兩點的影響)
2,事務的提交Commit
Redo Log Buffer的寫盤,由變數innodb_flush_log_at_trx_commit決定,有三種模式分別是0,1,2
如果設置為0,事物提交不觸發Redo Log Buffer寫盤,每N秒將Redo Log Buffer的記錄寫入Redo Log文件,並且將Redo Log文件刷入硬體存儲1次,N由innodb_flush_log_at_timeout控制。
如果設置為1,事務提交時同步刷新Redo Log Buffe到Redo Log文件,並且將Redo Log文件刷新到磁碟。
如果設置為2,事務提交時同步刷新Redo Log Buffe到Redo Log文件,.但是Redo Log 的flush(刷到磁碟)操作並不會同時進行。Redo Log的寫盤由操作系統和innodb_flush_log_at_timeout控制。
需要註意的是,innodb_flush_log_at_trx_commit=1的情況下,儘管事務提交可以保證redo log同步寫盤,
但是Redo Log Buffer的寫盤並不一定只有在事務提交的時候才寫入的,有可能是隨著時候的執行(如果事務很大)逐步寫盤的。
3,事務提之後
因為redo log的存在(寫盤之後),事務的一致性和持久性得到了保證,對於記憶體中的臟數據,通過checkpoint或者記憶體機制刷入磁碟,在數據寫入磁碟之後,redo log空間即可釋放
對於undo log,當沒有活動Session訪問的時候,由purge線程非同步清理undo log占用的空間
見不少人寫博客使用xmind或者其他工具對相關知識點進行整理,
發現類似於xmind的結構圖對於知識結構非常清晰,xmind第一份工作用過,好久沒用了,裝了試用版發現功能受限很多。
於是嘗試類似於xmind的線上工具,發現百度腦圖還可以,關鍵是線上的,隨時隨地就都可以打開整理相關的知識點。
參考:
https://segmentfault.com/a/1190000012650596
https://liuzhengyang.github.io/2017/04/18/innodb-mvcc/
MySQL技術內幕 InnoDB存儲引擎