A committed transaction must survive a crash; an aborted transaction must leave no visible effect. Recovery turns those promises into storage rules. The central idea is simple: record enough history before changing durable data, then use that history after failure.
Start by naming the failure
| Failure | What is lost or damaged | Main response |
|---|---|---|
| Transaction abort | One transaction’s partial work | Undo or discard its versions |
| Process or power failure | Volatile memory | Replay the log during restart |
| Storage-device failure | Database pages and perhaps local log | Restore backup, then apply archived log |
| Site loss | Machine or location | Fail over to an independent copy |
A backup is not a transaction log. A backup supplies an older complete state; the log explains how to advance that state and which incomplete work to remove.
In plain terms: a backup is a photograph. The log is the sequence of events recorded after the photograph was taken. Recovery often needs both.
The write-ahead rule
Write-ahead logging (WAL) imposes two ordering rules:
- Before a dirty data page reaches durable storage, the log record describing that change must be durable.
- Before the database reports
COMMITsuccess, the transaction’s commit record must be durable.
The first rule makes undo or redo possible even if a changed page is written early. The second makes the client-visible meaning of commit honest. WAL does not require every data page to be flushed at commit; usually only the log is forced.
transaction changes page in memory
│
├── append log record
├── flush log through COMMIT
└── reply success
dirty page may reach disk later
Why STEAL and FORCE matter
Two buffer-manager choices determine the recovery work:
| Policy | Meaning | Consequence |
|---|---|---|
| STEAL | An uncommitted dirty page may be written | Recovery may need UNDO |
| NO-STEAL | Uncommitted pages stay in memory | No on-disk uncommitted update |
| FORCE | All changed pages are flushed at commit | Committed work needs no REDO |
| NO-FORCE | Commit may leave dirty pages in memory | Recovery may need REDO |
Most high-performance systems favor STEAL + NO-FORCE: memory can be reused and commit does not wait for many random page writes. The price is support for both undo and redo.
What restart recovery actually asks
After a crash, recovery must classify log records around the failure boundary:
- Which transactions committed? Their effects may require redo.
- Which transactions were still active? Their visible on-disk effects may require undo.
- Which page updates are already reflected on disk? Page metadata such as a log sequence number helps avoid repeating unnecessary work.
An idempotent redo operation is safe to consider more than once. Recovery checks whether a page already includes a change before applying it.
Checkpoints bound the search
A checkpoint records enough information about active transactions and dirty pages to avoid scanning from the beginning of the log. It does not replace WAL and it does not necessarily flush the entire database.
More frequent checkpoints usually shorten restart work but create more foreground I/O. Less frequent checkpoints reduce that overhead but increase recovery time. The useful target is a tested recovery-time objective, not “as often as possible.”
Recovery beyond one database
Recovery becomes harder when an operation crosses services. A local database can undo bytes using its log; an external email, payment, or shipment cannot be physically undone the same way. Those workflows need idempotency keys, retry records, and compensating business actions.
This is also why “we have replicas” is not a backup strategy. Replication can faithfully copy accidental deletion or corruption. Recovery plans should cover point-in-time restore, credential loss, regional failure, and regular restore drills.
Review card
- WAL reaches durable storage before the data page it describes.
- A commit response requires a durable commit record.
- STEAL creates a possible undo requirement; NO-FORCE creates a possible redo requirement.
- A checkpoint limits recovery work; it does not replace the log.
- Backup, replication, and transaction logging solve different failure modes.
- A recovery design is incomplete until restore time and data loss are tested.
已 commit 的 transaction 必須在 crash 後留下;abort 的 transaction 不應留下可見影響。Recovery 的工作,就是把這兩句承諾變成 storage rule:先留下足夠歷史,再改 durable data;發生故障後用歷史把狀態補回來。
先分清楚是哪一種故障
| 故障 | 損失或損壞的內容 | 主要處理方式 |
|---|---|---|
| Transaction abort | 單一 transaction 的部分修改 | Undo 或丟棄其 version |
| Process/斷電 | Volatile memory | Restart 時 replay log |
| Storage device 故障 | Data page,可能連 local log 也失去 | 還原 backup,再套 archived log |
| Site loss | 整台機器或地點 | 切換到獨立副本 |
Backup 不是 transaction log。Backup 提供較舊但完整的狀態;log 則說明照片拍完後發生了什麼,以及哪些未完成工作要移除。
白話來說: Backup 是照片,log 是照片拍完後的事件紀錄。完整復原通常兩個都要。
Write-ahead rule
Write-ahead logging(WAL)有兩個順序要求:
- Dirty data page 落到 durable storage 前,描述該修改的 log record 必須先 durable。
- Database 回覆
COMMIT成功前,該 transaction 的 commit record 必須先 durable。
第一條保證 page 提早寫出時仍有資料可 undo/redo;第二條保證 client 看到的 commit 不是空口承諾。WAL 不要求 commit 時把全部 data page 都 flush,通常只需要先 force log。
transaction 在 memory 修改 page
│
├── append log record
├── flush log 到 COMMIT
└── 回覆成功
dirty page 可以之後才寫入 disk
STEAL 與 FORCE 決定復原工作
| Policy | 意義 | 後果 |
|---|---|---|
| STEAL | 未 commit 的 dirty page 可以被寫出 | 可能需要 UNDO |
| NO-STEAL | 未 commit page 留在 memory | Disk 不會有未 commit 修改 |
| FORCE | Commit 時全部 modified page 都寫出 | Committed work 不需 REDO |
| NO-FORCE | Commit 後 dirty page 可留在 memory | 可能需要 REDO |
高效能系統通常偏向 STEAL + NO-FORCE:buffer 能提早釋放,commit 不必等待多個 random page write。代價是 recovery 必須同時支援 undo 與 redo。
Restart 時真正要回答的問題
Crash 後,recovery 會沿著 log 判斷:
- 哪些 transaction 已 commit?其效果可能要 redo。
- 哪些 transaction 當時仍 active?已落盤的修改可能要 undo。
- 哪些 page 已包含某次修改?Page 上的 log sequence number 可避免重做無用工作。
好的 redo 能安全地被重新考慮。Recovery 會先檢查 page 是否已包含該變更,再決定要不要套用。
Checkpoint 是縮短搜尋,不是取代 log
Checkpoint 記錄 active transaction 與 dirty page 等資訊,讓 restart 不必從 log 開頭掃起。它不等於 WAL,也不必然把整個 database flush 完。
Checkpoint 越頻繁,restart 通常越快,但 foreground I/O 越多;頻率較低則相反。正確目標不是「越常越好」,而是實際測過的 recovery-time objective。
離開單一 database 之後
跨 service 的 recovery 更難。本地 database 能依 log undo bytes;已寄出的 email、已請款的 payment、已出貨的 package 無法用同樣方式物理 undo。這類 workflow 需要 idempotency key、retry record 與具有業務語意的 compensation。
同樣地,「有 replica」也不等於有 backup。Replica 可能忠實複製誤刪或 corruption。Recovery plan 要涵蓋 point-in-time restore、credential loss、region failure,並定期真的做 restore drill。
複習卡
- WAL 必須先於其描述的 data page 落盤。
- 回覆 commit 前,commit record 必須 durable。
- STEAL 帶來 undo 需求;NO-FORCE 帶來 redo 需求。
- Checkpoint 限制 recovery 工作量,但不取代 log。
- Backup、replication 與 transaction log 處理不同 failure mode。
- 沒有測過 restore 時間與資料損失的 recovery plan,仍只是文件。