Undo/Redo 日志 — 知识地图
本笔记为 MOC(Map of Content)
Undo 日志用于回滚事务(记住”旧值”),Redo 日志用于崩溃恢复(记住”新值”)。两者配合,共同保证数据库的原子性和持久性。
原子笔记
Undo vs Redo 对比
| 对比项 | Undo 日志 | Redo 日志 |
|---|---|---|
| 记录内容 | 修改前的值(旧值) | 修改后的值(新值) |
| 用途 | 回滚事务、读一致性 | 崩溃恢复、持久性 |
| 写入时机 | 修改数据前 | 修改数据后/提交前 |
| 作用方向 | 反向操作(撤销) | 正向操作(重做) |
| 生命周期 | 事务结束前保留 | 持久化到事务提交后 |
完整的事务流程
sequenceDiagram participant T as 事务 participant UL as Undo Log participant RL as Redo Log participant DB as 数据库 T->>UL: 1. 记录Undo日志(修改前的值) Note over UL: 此时可以回滚 T->>DB: 2. 修改数据页(内存) T->>RL: 3. 记录Redo日志(修改后的值) T->>RL: 4. Redo日志刷盘 T->>T: 5. 提交事务 Note over T,DB: 此时已提交事务的修改<br/>不会丢失(崩溃恢复时重做) T->>DB: 6. 数据页异步刷盘 T->>UL: 7. 释放Undo日志
崩溃恢复流程
flowchart TD A[系统启动] --> B[读取日志文件] B --> C{分析阶段} C -->|确定已提交事务| D[标记为需要重做] C -->|确定未提交事务| E[标记为需要回滚] D --> F[Redo阶段] E --> G[Undo阶段] F --> F1[从头扫描Redo日志] F1 --> F2{检查事务状态} F2 -->|已提交| F3[重做:应用新值] F2 -->|未提交| F4[跳过] G --> G1[从尾扫描Undo日志] G1 --> G2{回滚未提交事务} G2 --> G3[应用Undo:恢复旧值] F3 --> H[恢复完成] F4 --> H G3 --> H style H fill:#90EE90
核心要点
┌────────────────────────────────────────────────────────┐
│ Undo/Redo 要点 │
├────────────────────────────────────────────────────────┤
│ │
│ Undo 日志: │
│ ├── 记录"旧值",用于回滚 │
│ ├── 支持 MVCC 和读一致性 │
│ └── 事务回滚时必须 │
│ │
│ Redo 日志: │
│ ├── 记录"新值",用于重做 │
│ ├── 先于数据页写入磁盘(WAL) │
│ └── 崩溃恢复时必须 │
│ │
│ 两者结合: │
│ ├── 保证原子性(Undo) │
│ ├── 保证持久性(Redo) │
│ └── 支持高效的崩溃恢复 │
│ │
└────────────────────────────────────────────────────────┘
面试要点
Q:能否只用 Undo 或只用 Redo?
A:
- 只用 Undo:无法恢复已提交事务的修改(丢失持久性)
- 只用 Redo:无法回滚未提交事务(无法保证原子性)
- 两者都需要,缺一不可