cmu15545筆記-WAL和資料庫恢復

咪啪魔女發表於2024-12-09

目錄
  • 總覽
  • 快取策略(Buffer Pool Policies)
    • Shadow Paging(No-Steal + Force)
    • SQLite Rollback Mode(Steal + Force)
    • 總結
  • WAL(Write-Head Log)
    • 基本思想
    • 日誌格式 (Log Schemes)
    • 檢查點(Check Point)
  • ARIES演算法
    • 日誌序列號
    • 事務提交流程
    • 模糊檢查點(Fuzzy CheckPointing)
    • ARIES恢復演算法

總覽

該筆記包含了原課程中關於資料庫恢復的兩節課的內容:

  • 資料庫日誌(Database Logging)
  • 資料庫恢復(Database Recovery)

資料庫的事務併發控制保障了資料庫在正常執行時的原子性隔離性一致性,但是當資料庫在執行事務過程中當機了,導致事務無法正常執行時,該怎麼辦呢?

image image

此時就需要資料庫的恢復機制,來保障異常時,事務的原子性持久化,而恢復機制的核心思想就是日誌(Logging)。

日誌包括Redo日誌Undo日誌,分別用來重做資料庫當機前已經提交的日誌,和撤銷未提交的日誌。

恢復機制分為兩個部分:

  1. 事務執行過程中,如何記錄日誌,確保可以從當機中恢復。
  2. 當機後,怎麼利用日誌恢復到滿足一致性的狀態,主要採用ARIES演算法。

快取策略(Buffer Pool Policies)

會有資料庫恢復問題,根本原因是為了利用記憶體更新快的特性,資料庫的緩衝區和磁碟資料沒有立刻同步,導致資料不一致。

因此,在介紹資料庫日誌之前,有必要先了解不同的快取策略,會給資料庫恢復問題早餐哪些影響。

  • Steal和No-Steal:是否刷髒
  • Force和No-Force:事務結束後是否先寫回磁碟再提交成功

Shadow Paging(No-Steal + Force)

不需要恢復策略。

  • Master Pointer:指向當前使用的緩衝區
  • 開啟時:複製一個緩衝區,緩衝區指向後設資料
  • 更新資料時:磁碟上覆制後設資料,然後對應緩衝區指向新資料
  • 提交時:將Master Pointer指向新緩衝區
image image

Redo:不需要,因為Force保證只要提交成功,就已經刷盤。

Undo:不需要,No-Steal保證沒有提交的事務不會寫入磁碟,所以把記憶體中的無用緩衝區清理掉即可。

SQLite Rollback Mode(Steal + Force)

在修改資料之前,要先把原資料寫入磁碟中(SQLite 稱為 Journal File)。

  • 開啟時:建立空Journal File
  • 更新資料時:先把後設資料寫入Journal File,再更新緩衝區資料
  • 提交時:刪除Journal File,資料落盤

Redo:不需要。

Undo:檢查是否有Journal File,有則重新寫入磁碟即可。

image image

總結

Steal需要做Undo,No-Force需要做Redo。

No-Steal+Force不需要額外恢復措施,但是效能弱。

Steal+No-Force需要Redo+Undo恢復手段,但是效能高。

大多數資料庫都是 Steal+No-Force。

image-20241209113056953

WAL(Write-Head Log)

基本思想

更新資料的時候同步新增資料修改日誌,事務返回成功前保證日誌已經落盤。

日誌結構:

  • <BEGIN>:事務開始
  • <LSN, preLSN, TxnId, Type, ObjectId, Before Value, End Value, UndoNextLSN>
    • TxnIdObjectId記錄事務和物件資訊
    • Before Value用於Undo,After Value用於Redo。
    • LSN見後文描述
  • <Commit>:事務提交

如果使用Append-Only型MVCC可以不需要Before Value

image-20241209113913257

怎麼區分要做Redo還是Undo:事務是否提交。未提交做Undo,提交了做Redo。

從哪裡開始做Redo和Undo:檢查點Check Point。儲存點之前到日誌都已經刷盤,恢復時只需要對儲存點之後到日誌做Redo和Undo。

Group Commit最佳化:日誌緩衝區滿了或者到一定時限(e.g. 5ms),將日誌緩衝區落盤,而不是每次事務提交都落盤,以此減少IO次數。

日誌格式 (Log Schemes)

形式 優點 缺點
物理日誌(Physical Log) 位元組變動記錄日誌 恢復快 日誌大
邏輯日誌(Logical Log) 一般是SQL語句 日誌小 每次執行結果不一定一致(如時間和隨機數函式,併發訪問性問題)
物理邏輯日誌(Phylogical Log) PageId + Slot Number
"Physical-to-a-page, logical-within-a-page"
- -

Phylogical Log是一種折中,現在大多數資料庫都採用這種形式。

image-20241209120057809

檢查點(Check Point)

減少資料恢復時的資料寫回量,將全量恢復變成增量恢復,加快恢復速度。

步驟如下:

  1. 停滯所有查詢
  2. 將WAL記錄刷盤
  3. 將髒頁刷盤
  4. <CheckPoint>寫入WAL並刷盤
  5. 恢復查詢

CheckPoint作為恢復時日誌分析的起點:CheckPoint後提交的事務做Redo,未提交的做Undo。

image-20241209121906313

ARIES演算法

基本思想:WAL;Undo時記錄撤銷日誌。

image-20241209144306290

日誌序列號

日誌序列號(Log Sequence Number),作為日誌Id標識日誌。

名稱 位置 定義
flushedLSN 記憶體 上次刷盤時的LSN
pageLSN 快取頁 該頁上最新更新的LSN
MasterRecord 磁碟 檢查點的LSN
recLSN 髒頁表 上次刷盤後的第一個LSN
(第一個未刷盤的LSN)
lastLSN 活動事務表 該事務的最新LSN

image-20241209144414632

流程:

  • 事務更新一個頁時,更新該頁的pageLSN

  • 日誌刷盤時,更新flushedLSN

  • 快取頁刷盤時判斷:pageLSN <= flushedLSN允許資料落盤,否則不允許,因為日誌還沒落盤。

image image

事務提交流程

新增下面兩種日誌型別:

  • TXN-END日誌:表示事務生命期結束,後續日誌不會再出現該事務。

新增TXN-END前必須保證當前事務的髒頁都刷入磁碟。

  • CLR日誌:事務Abort和Crash之後,未提交事務需要進行回滾,CLR日誌(Compensation Log Record)記錄回滾這一行為。

正常提交:走上文提到的流程。

Abort提交:

  1. ABORT記錄寫進日誌
  2. 利用日誌中的preLSN不斷回溯進行undo,對於每個更新記錄
    • 記錄CLR Record
    • 恢復資料
  3. TXN-END寫進日誌

image-20241209150854563

正常提交時,TXN-END接在COMMIT之後;Abort時,ABORTTXN-END之間是CLR Records。

模糊檢查點(Fuzzy CheckPointing)

原有檢查點的問題:需要將所有髒頁刷盤;停止所有事務,避免刷盤過程中產生新的髒頁;不確定當前有哪些活動事務,導致需要重放所有日誌確定哪些日誌沒有提交。

模糊檢查點:將檢查點由一個時間點變成時間段,並且記錄活動事務(ATT)和髒頁(DPT)。

  • CHECKPOINT-BEGIN:檢查點開始
  • CHECKPOINT-END:記錄ATT+DPT

image-20241209165148155

ARIES恢復演算法

總過程

  1. 分析階段:構建DPT和ATT
  2. Redo階段:從DPT找到最小的recLSN(從此處開始未刷盤),開始Redo
  3. Undo階段:從ATT找到每個活動事務的lastLSN(該事務的最新LSN),用preLSN逆推所有修改,開始Undo

image-20241209165534496

分析階段:從CHCKPOINT-BEGIN開始

  • 每遇到一個事務,新增到ATT,狀態為U
  • 每遇到一個髒頁,新增到DPT
  • 每遇到一個COMMIT,修改事務狀態為C;TXN-END,將事務移除ATT
  • 過程中,維護DPT表的lastLSN和ATT表的recLSN

image-20241209170755470

Redo階段

  1. 找到DPT中最小的reclSN
  2. 對於每個update log record和CLR,進行重做,除非:
    • 不在DPT內
    • 在DPT內,但是LSN < 最小的recLSN
    • LSN <= pageLSN
  3. 對於所有狀態為C的事務,新增TXN-END,然後從ATT中刪除。

Undo階段:對於每個狀態為U的事務,用recLSN逆推所有更新,新增CLR

例子如下,沒有體現Redo過程:

Crash前:

image-20241209184420705

兩次Crash後,\(T_2\)\(T_3\)已經提交TXN-END,從ATT表刪除。

image-20241209172804709

相關文章