第 8 章 · 04 预写日志(WAL)与崩溃恢复


文档摘要

第 8 章 · 04 预写日志(WAL)与崩溃恢复 本节摘要:数据库最怕「写一半断电」。预写日志(WAL,Write-Ahead Log)是解决这个问题的标准方案:先把要做的改动记进日志(顺序写,快),再改实际数据(随机写,慢)。崩溃后重放日志,要么把没做完的做完,要么把没提交的撤销。本节讲清 WAL 的工作原理与崩溃恢复流程,这是「持久性」的工程实现,呼应第 6 章 Git 的「原子提交」思想。 内容来源:基于数据库持久化整理的导读。 学习目标 说清 WAL 的核心:「先记日志,再改数据」。 解释为什么先写日志(顺序写快)再改数据(随机写慢)反而更可靠。 描述崩溃恢复:重放日志,补做未完 / 撤销未提交。 理解 WAL 与第 6 章 Git 原子提交思想的呼应。

第 8 章 · 04 预写日志(WAL)与崩溃恢复

本节摘要:数据库最怕「写一半断电」。预写日志(WAL,Write-Ahead Log)是解决这个问题的标准方案:先把要做的改动记进日志(顺序写,快),再改实际数据(随机写,慢)。崩溃后重放日志,要么把没做完的做完,要么把没提交的撤销。本节讲清 WAL 的工作原理与崩溃恢复流程,这是「持久性」的工程实现,呼应第 6 章 Git 的「原子提交」思想。

内容来源:基于数据库持久化整理的导读。

学习目标

  1. 说清 WAL 的核心:「先记日志,再改数据」。
  2. 解释为什么先写日志(顺序写快)再改数据(随机写慢)反而更可靠。
  3. 描述崩溃恢复:重放日志,补做未完 / 撤销未提交。
  4. 理解 WAL 与第 6 章 Git 原子提交思想的呼应。

一、学习价值:持久性的工程实现

数据库的 ACID 里,「D(持久性)」——提交了就不丢——是最难保证的。磁盘写一半断电,数据可能损坏。WAL 是工业界的标准解法,几乎所有数据库(SQLite、MySQL、PostgreSQL)都用它。理解 WAL,你才理解「为什么数据库能承诺持久性」,以及「fsync 为何重要」。

二、子系统拆解

问题:为什么直接改数据不安全

朴素做法:每次修改直接改数据页,定期刷盘。问题:改一个数据页可能跨多个磁盘块,写到一半断电,这个页就损坏了。而且数据页是随机写(改哪写哪),慢。

WAL 的解法:先记后做

修改操作: 1. 把「要做什么改动」记进 WAL 日志(追加, 顺序写, 快) 2. fsync 日志(确保日志真落盘) 3. 才改实际数据页(随机写, 慢, 可延迟批量刷盘)

关键:日志先落盘,数据后改。崩溃后:

  • 若日志写了但数据没改:重放日志,把改动应用(补做)。
  • 若日志没写完(事务未提交):丢弃(撤销)。

这样,只要「日志写了」就算「提交成功」,数据页可以慢慢刷盘(性能好),崩溃靠日志恢复。

为什么先日志(顺序写)反而快

顺序写(日志追加)比随机写(改数据页)快几个数量级(磁盘的机械特性:顺序不用移动磁头,SSD 顺序也更快)。WAL 把「确保可靠」的负担放在快的顺序写上,把慢的随机写延迟批量做——既可靠又快。

崩溃恢复

启动时检查 WAL:

  1. 读日志里所有「已提交」的记录,重放(把改动应用到数据页)。
  2. 「未提交」(日志没写完)的记录,丢弃。

恢复后,数据页状态 = 最后一次提交的完整状态——持久性得到保证。

与 Git 原子性的呼应

第 6 章造 Git 时,commit 是「原子的」(要么完整存在,要么不存在)。WAL 让数据库也获得类似原子性:事务要么完整(日志写了)、要么不存在(日志没写),不会「半提交」。两者都靠「先写不可变记录,再改可变状态」的模式。

三、上手第一步

  1. 给每个修改操作加日志记录(操作类型 + 数据 + 事务标识)。
  2. 改数据前先写日志 + fsync。
  3. 启动时检查日志,重放未应用到数据页的已提交记录。
  4. 测试:写一半 kill 进程,重启后数据应一致。

本节要点回顾

  1. WAL 核心:「先记日志(顺序写快+fsync),再改数据(随机写慢,可延迟)」。
  2. 可靠性:日志写了=提交成功;崩溃靠重放日志恢复,要么补做要么撤销。
  3. 性能:顺序写(日志)比随机写(数据)快,WAL 把可靠负担放快的写上。
  4. 崩溃恢复:重放已提交日志、丢弃未提交,恢复到最后一次提交状态。
  5. 呼应 Git:两者都用「先写不可变记录,再改可变状态」实现原子性。

推荐上手顺序

  1. 给修改操作加日志记录。
  2. 改数据前先写日志+fsync。
  3. 启动重放日志。
  4. kill 测试崩溃恢复。
  5. 下一节:事务与综合。

下一节讲事务 ACID 与综合。


发布者: 作者: 灏天文库 转发
评论区 (0)
U