intro
- 日志順序號(LSN)
- 支持物理邏輯redo。它是物理的,但在頁內它可能是邏輯的。
- 使用臟頁表來最大限度地減少恢復時不必要的重做。
- 使用模糊檢查點機制,只記錄臟頁信息和相關的信息,甚至不要求將臟頁寫到磁盤。不在檢查點時將臟頁寫入磁盤,而是連續地在后台刷新臟頁面。
數據結構
LSN
每個日志記錄都有一個唯一標識該記錄的日志順序號(LSN)。
LSN:由一個文件號以及在該文件中的偏移量組成。
每一頁也維護一個叫頁日志順序號(PageLSN)的標識。每當一個更新操作發生在某頁上時,該操作將其日志記錄的LSN存儲在該頁的PageLSN域中。在恢復的撤銷階段,LSN值小於或等於PageLSN值的日志記錄將不在該頁上執行,因為它的動作已經在該頁上了。
每個日志記錄包含同一事務的前一日志記錄的LSN,放在PrevLSN中,使得一個事務可以由后向前提取,而不必讀整個日志。事務回滾中會產生一些特殊的redo-only的日志,稱為補償日志記錄(Compensation Log Record, CLR)。CLR中還有額外的稱為UndoNextLSN的字段,記錄下一個需要undo的日志的LSN。
臟頁表
包含一個在數據庫緩沖區中已經更新的頁的列表,為每一頁保存其PageLSN和一個稱為RecLSN的字段。RecLSN用於標識已經實施於該頁的磁盤上的版本的日志記錄。當某頁首次被放入臟頁表中,它的RecLSN值被設置為日志的當前末尾。
檢查點日志記錄
包含臟頁表和活動事務的列表。
恢復算法
恢復的過程包含三個階段:
- 分析階段:決定哪些事務要撤銷,哪些頁在崩潰時是臟的,以及重做階段應從哪個LSN開始
- redo階段:從分析階段決定的位置開始,執行重做,將DB恢復到發生崩潰前的狀態
- undo階段:這一階段回滾在發生崩潰時那些不完全的事務
分析階段
找到最后的完整檢查日志記錄,將該記錄讀入臟頁表。將redoLSN設為臟頁表中頁的RecLSN的最小值。
將undo-list初始設置為檢查點日志記錄中的事務列表,從檢查點正向掃描,發現新的begin,就加入;發現end,就刪去。也記錄undo-list每一個事務的最后一個記錄,在undo階段使用。
一旦有更新頁的記錄,不在臟頁表,也加入臟頁表。
redo階段
找到一個更新日志記錄:
- 如果該頁不在臟頁表中,或者該更新日志記錄的LSN小於臟頁表中該頁的RecLSN,跳過
- 否則從磁盤中調出該頁,如果其PageLSN小於該日志記錄的LSN,就重做。
undo階段
對日志進行一遍反向掃描,對undo-list中的所有事務進行撤銷。
用分析階段所記錄的每一個事務的最后一個LSN來快速定位。
每找到一個更新日志記錄,就用它來執行一個undo。
產生一個包含undo的CLR,並將該CLR的UndoNextLSN設置為該更新日志記錄的PrevLSN。
如果遇到一個CLR,它的UndoNextLSN已經指明需要Undo的LSN,且應該已經回滾。