崩了之后怎么救回数据:核心是日志——先写日志、后写数据(WAL),再靠 undo/redo 双向修复。
| 故障 | 影响范围 | 数据是否损坏 | 恢复手段 |
|---|---|---|---|
| 事务故障 | 单个事务(逻辑错/死锁被回滚) | 否,内存/未提交 | undo 回滚 |
| 系统故障 | 整个系统(掉电/崩溃) | 内存丢失,磁盘数据在 | redo + undo |
| 介质故障 | 磁盘损坏 | 是,数据真没了 | 备份 + redo 日志重放 |
关键:前两类磁盘数据没丢,只需「已提交的重做、未提交的撤销」;介质故障得靠备份副本 + 日志。
事务 T:A = A - 100
redo 日志:<T, A, 新值> → 崩溃后重做,把 A 写成新值
undo 日志:<T, A, 旧值> → 回滚时撤销,把 A 写回旧值
对比:redo vs undo——redo 面向已提交,向前推到提交后状态,解决持久性;undo 面向未提交,向后拉回事务前状态,解决原子性。一次系统故障恢复 = 先 redo 已提交,再 undo 未提交。
WAL(预写式日志) 是恢复正确性的根基,规则一条:
任何数据页落盘之前,它对应的日志必须先落盘(先写日志,后写数据)
若数据页落盘后、日志还没写就崩溃,已提交修改无法重做,持久性被破坏。WAL 保证日志先于数据,崩溃后总能从日志重建正确状态;且把随机写(数据页)转成顺序追加写(日志),反而更快。
恢复若每次从头扫日志代价不可接受。检查点定期做三件事:
<CHECKPOINT> 记录(含当时活跃事务清单);时间轴: ... 检查点C1 ... 检查点C2 ... ─崩溃─▶ 恢复
恢复只需处理 C2 之后的事务,C2 之前已落盘
检查点越频繁恢复越快,但正常运行刷盘开销越大。
对比:三种故障恢复——事务故障最轻,仅内存层 undo;系统故障磁盘完好,用 redo + undo 拉到一致,扫最近检查点后日志;介质故障最重,须备份 + 重放日志,备份间隔决定数据丢失窗口(RPO)。共同点:都靠日志——日志是恢复的唯一真相来源。