概念
數據庫文件data file;
數據庫緩存db buffer;
日志緩存log buffer;
磁盤日志文件log file;
Undo日志記錄某數據被修改前的值,可以用來在事務失敗時進行rollback;Redo日志記錄某數據塊被修改后的值,可以用來恢復未寫入data file的已成功事務更新的數據。
例如某一事務的事務序號為T1,其對數據X進行修改,設X的原值是5,修改后的值為15,那么Undo日志為<T1, X, 5>,Redo日志為<T1, X, 15>。
undo和redo結合起來的做法,叫做Undo/Redo日志,在這個例子中Undo/Redo日志為<T1, X, 5, 15>。
當用戶生成一個數據庫事務時,undo log buffer會記錄被修改的數據的原始值,redo會記錄被修改的數據的更新后的值。
redo日志應首先持久化在磁盤上,然后事務的操作結果才寫入db buffer,(此時,內存中的數據和data file對應的數據不同,我們認為內存中的數據是臟數據),
db buffer再選擇合適的時機“刷盤”,將數據持久化到data file中。這種順序可以保證在需要故障恢復時恢復最后的修改操作。
在innodb中用戶提交事務完成以后,有可能數據還沒有寫到磁盤,此時內存中的db buffer和數據文件內容不一致,這種頁面稱為臟頁,將臟頁記錄到磁盤的過程稱為刷臟。
刷臟有兩種算法:flush-list(時間管理緩沖池刷臟)和LRU-list(最近最久未使用【使用頻率】)。mysql5.6開始引入了page cleaner線程,專門負責刷臟。
1,LRU-list-flush,其目的是為了在 LRU 鏈表尾部釋放足夠的free pages;當 buf pool 滿的時候, 用戶可以立即獲得空閑頁面,而不需要長時間等待; Flush-list-flush,其目的是推進 Checkpoint LSN,使得 InnoDB 系統崩潰之后能夠快速的恢復。
2,LRU-list-flush,釋放后的free page,需要移動到 LRU 鏈表的尾部(MySQL 5.6.2 之前版本);或者是直接從 LRU 鏈表中刪除,移動到 free list(MySQL 5.6.2 之后版本)。 Flush-list-flush,不需要移動 page 在 LRU 鏈表中的位置。
3,LRU-list-flush,每次 flush 的 dirty pages 數量較少,基本固定,只要釋放一定的 free pages即可; Flush-list-flush,根據當前系統的更新繁忙程度,動態調整一次 flush 的 dirty pages數量更大。