Skip to main content
☘️ Septvean's Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

WAL

一、WAL 的概念

WAL = Write-Ahead Logging(预写日志)

核心思想:先记录日志,再修改数据

  • 所有对数据库的修改,先写入 WAL 日志文件
  • 只有日志写入成功,事务才算提交
  • 数据页可以延迟刷盘,保证崩溃恢复时可回滚或重做

WAL 的目的

  1. 事务持久性(Durability)

    • 数据修改未落盘,系统崩溃也能恢复
  2. 崩溃恢复(Crash Recovery)

    • 系统挂掉,重放 WAL 可恢复未落盘的数据
  3. 高性能写入

    • 避免每次修改都直接刷磁盘
    • 顺序写日志比随机写数据快很多
  4. 支持复制

    • WAL 可用于流复制(PostgreSQL)或 binlog(MySQL)

二、WAL 的原理

  1. 事务修改 -> 写 WAL 日志
  2. 日志刷盘(fsync) -> 事务提交
  3. 脏页延迟刷盘 -> 数据页异步写入磁盘
  4. 崩溃恢复
    • Redo 日志:回放 WAL,保证修改持久
    • Undo 日志:回滚未提交事务(部分数据库通过 MVCC 或 redo/undo 实现)

WAL 的典型写入顺序

事务开始
  |
  v
修改 -> 写 WAL
  |
  v
fsync WAL(保证持久)
  |
  v
事务提交
  |
  v
异步写入数据页

三、WAL 的数据结构

以 PostgreSQL 为例:

  1. WAL 记录结构

    • Log Sequence Number (LSN):每条 WAL 的唯一标识
    • 页级修改记录:记录数据页变化
    • 事务号、时间戳、操作类型
  2. 磁盘布局

    • WAL 分段文件(通常 16MB/32MB)
    • 顺序写入,追加模式
    • 顺序 fsync,避免随机写
  3. WAL 重放

    • 按 LSN 顺序扫描
    • redo 修改数据页
    • undo 撤销未提交事务

四、MySQL 与 PostgreSQL 的 WAL 差异

特性 PostgreSQL WAL MySQL InnoDB redo log
叫法 WAL redo log (也称 redo)
事务提交 WAL 写入 fsync -> 提交 redo log 写入 buffer -> flush 或 group commit
数据页写入 异步刷脏页 异步刷脏页
文件类型 WAL segment files redo log files (循环)
事务恢复 通过重放 WAL redo log 重做,undo log 回滚
MVCC 关系 直接支持 MVCC InnoDB MVCC 使用 undo log
复制 WAL 可流复制 binlog 复制(逻辑复制)

五、WAL 的性能优化点

  1. 顺序写优势

    • WAL 写入顺序,磁盘 IO 效率高
  2. fsync 策略

    • 每事务 fsync -> 最安全,但慢
    • batch fsync / group commit -> 性能高
  3. 志压缩/分段

    • PostgreSQL 分段文件
    • MySQL redo 循环日志
  4. 异步刷盘

    • 数据页可以延迟写入,提高吞吐

六、WAL 的应用场景

  1. 崩溃恢复

    • PostgreSQL 挂掉 -> 重放 WAL -> 完整恢复
    • MySQL InnoDB 崩溃 -> redo log 回滚/重做
  2. 逻辑/流复制

    • PostgreSQL 流复制 -> 直接传 WAL
    • MySQL binlog -> redo + binlog 逻辑复制
  3. 热备 / 增量备份

    • WAL 可增量备份
    • 支持 PITR(Point-In-Time Recovery)

七、总结

WAL 是数据库保证事务持久性和崩溃恢复的核心机制:修改先写日志再改数据页,日志顺序写磁盘,高性能并支持复制和增量备份。