从一个生活故事说起
想象一下,你正在经营一家小超市。每天都会有很多笔交易发生:顾客买东西、供应商送货、员工换班交接等。如果没有一个可靠的记录方式,会出现什么情况呢?
场景一:凭记忆经营
-
顾客A买了牛奶和面包,你心里记着要更新库存
-
这时突然有人找你问价格,打断了你的思路
-
结果你只记得更新了牛奶的库存,忘记了面包
-
月底盘点时,发现库存对不上,产生了损失
场景二:边记账边干活
-
你先在账本上记录“卖出牛奶1盒”
-
然后去仓库取出牛奶交给顾客
-
如果中途被打断,回来看看账本就知道该做什么
-
即使突然停电,恢复后也能根据账本继续工作
这个“先记账后干活”的方法,就是预写日志(WAL)的核心思想!
什么是预写日志?
简单定义
预写日志是一种数据安全保护机制,它的基本原则是:在真正修改数据之前,先把要做什么事记录下来。
就像我们写日记:
-
先在本子上写下“明天要去银行存钱”
-
第二天按照记录去执行
-
如果中途生病了,康复后看看日记就知道该做什么
技术上的比喻
把数据库想象成一个仓库:
-
数据文件 = 仓库里的货物架
-
预写日志 = 仓库的出入库记录本
-
数据库操作 = 实际的货物搬运
WAL的工作方式:
收到指令 → 记录到日志本 → 确认记录完成 → 执行实际操作
为什么需要WAL?
没有WAL时的问题
让我们通过一个银行转账的例子来说明:
假设A向B转账100元,需要两个步骤:
1. A账户减100元
2. B账户加100元
没有WAL的危险场景:
系统崩溃风险
时间线:
[A账户已扣款] → 系统崩溃! → [B账户未加钱]
结果:A白白损失100元,数据不一致!
部分成功问题
操作顺序:
- 先修改A账户:1000元 → 900元 ✓
- 准备修改B账户时,磁盘满了
- 结果:A的钱少了,B的钱没多
恢复困难
崩溃后重启:
- 看到A账户只有900元
- 但不知道是因为转账,还是其他原因
- 无法确定该不该给B加100元
WAL如何解决这些问题
有WAL的安全场景:
完整的操作流程
时间线:
[记录日志:"A转100给B"] → [确认日志保存] → [执行A扣款] → [执行B加款]
崩溃恢复机制
如果在这里崩溃:[执行A扣款] → 系统崩溃!
恢复过程:
- 重启后检查日志
- 发现"A转100给B"记录但未完成
- 重新执行:给B加100元
- 数据恢复一致!
WAL解决的核心问题
1. 原子性(Atomicity)保障
概念:一个操作要么完全成功,要么完全失败,没有中间状态。
WAL的实现:
-
开始操作前,记录“准备做什么”
-
所有步骤完成后,记录“已经做完了”
-
如果中途失败,根据日志回滚到开始状态
2. 持久性(Durability)保障
概念:一旦操作完成,结果就永久保存。
WAL的实现:
-
先确保操作记录持久化到稳定存储
-
然后再实际修改数据
-
即使数据修改中途失败,也有记录可以重试
3. 一致性(Consistency)保障
概念:数据始终处于合法状态。
WAL的实现:
-
通过完整的操作记录
-
确保数据从一个合法状态转换到另一个合法状态
-
不会停留在中间的不合法状态
WAL的工作原理
基本工作流程
让我们用图书馆借书来类比:

具体步骤:
日志记录阶段
-
收到“借阅《三体》”请求
-
在借阅本上写下:“张三借《三体》,时间:2024-01-20”
-
确认本子已经妥善放回抽屉
执行操作阶段
-
从书架上取出《三体》
-
在图书管理系统标记“已借出”
-
把书交给读者
完成确认阶段
-
在借阅本上标记“已完成”
-
如果中途停电,恢复后查看借阅本就知道哪些操作没完成
崩溃恢复过程
恢复时的处理逻辑:
系统重启后检查日志:
情况1:记录显示“开始转账”但没有“完成转账”
→ 重新执行转账操作
情况2:记录显示“开始转账”和“完成转账”
→ 什么都不做,操作已完成
情况3:记录显示“开始转账”和“取消转账”
→ 执行回滚操作
WAL的组成部分
1. 日志记录(Log Records)
就像日记的每一行,记录着:
-
做了什么操作(比如:更新、插入、删除)
-
操作的对象(比如:用户表的第5行)
-
修改的内容(比如:余额从1000改为900)
-
时间信息(操作顺序)
2. 日志缓冲区(Log Buffer)
相当于“草稿纸”:
-
临时存放即将写入的日志记录
-
积累一定数量后批量写入,提高效率
-
避免每条记录都直接写磁盘的速度问题
3. 检查点(Checkpoint)
相当于“阶段性总结”:
-
定期记录当前已完成的所有操作
-
减少崩溃后需要重放的日志数量
-
就像读书时在章节末尾做个标记
现实世界中的WAL应用
数据库系统
-
MySQL:使用redo log和undo log
-
PostgreSQL:WAL是核心组件
-
Oracle:重做日志文件
-
SQL Server:事务日志
分布式系统
-
ZooKeeper:事务日志保证一致性
-
Kafka:提交日志保证消息不丢失
-
Etcd:Raft日志复制
文件系统
-
ext4:日志记录元数据操作
-
NTFS:USN日志记录文件变更
-
ZFS:写时复制 + 事务日志
没有WAL会怎样?
数据损坏风险
实际案例:电力故障导致数据库损坏
- 没有WAL:部分数据永久丢失,需要从备份恢复
- 有WAL:自动恢复到最后一致状态,最多丢失几秒数据
业务中断影响
电商网站场景:
- 没有WAL:订单处理中断可能导致:
* 扣款成功但订单消失
* 库存减少但订单未生成
* 需要人工核对和修复
- 有WAL:自动恢复,保证订单完整性
运维复杂度
系统维护对比:
- 没有WAL:需要频繁备份,恢复过程复杂
- 有WAL:备份间隔可以更长,恢复自动化
WAL的代价与平衡
性能开销
付出的代价:
-
每次操作都要写日志,增加磁盘IO
-
日志需要持久化,可能成为性能瓶颈
-
需要额外的存储空间存放日志
获得的收益:
-
数据安全性和一致性
-
快速的崩溃恢复
-
系统可靠性大幅提升
现代优化技术
为了降低开销,现代系统采用:
-
组提交:多个操作合并写入,减少IO次数
-
异步写入:在安全前提下延迟持久化
-
日志压缩:定期清理过期的日志记录
WAL的价值所在
核心价值
预写日志就像数据的“保险单”:
-
付出少量保费(性能开销)
-
获得重大保障(数据安全)
-
关键时刻救命(崩溃恢复)
设计哲学
WAL体现了一个重要的工程原则:通过增加少量写操作来避免大量读修复。与其在出错后费尽心思修复数据,不如在操作前做好记录准备恢复。(扩展阅读:预写日志(WAL):数据持久化的守护者与现代架构创新)
现实意义
在当今数据驱动的时代,WAL技术:
-
保证银行交易不会丢钱
-
保证电商订单不会消失
-
保证社交信息不会错乱
-
保证医疗记录不会混乱
它可能不是最炫酷的技术,但却是支撑数字世界可靠运行的基石。就像建筑物的地基,平时看不见,却至关重要。
下次当你进行在线支付、提交订单或发送消息时,可以想想:背后正有一个“记账本”在默默保护你的数据安全呢!
1089

被折叠的 条评论
为什么被折叠?



