Oracle Redo、Undo 和归档日志有什么区别?
简化版
Redo 记录数据块如何被修改,用于崩溃恢复和介质恢复;Undo 保存修改前镜像,用于回滚和一致性读;归档日志是联机 Redo 日志切换后的归档副本,用于把数据库恢复到更长时间范围内的某个点。Redo 保证“做过的能重做”,Undo 保证“未提交的能撤销”。
详细版
Oracle 事务和恢复离不开 Redo 与 Undo:
- Redo:记录变更,提交时 LGWR 写入联机 Redo 日志。
- Undo:保存旧值,用于事务回滚和读一致性。
- Archived Redo Log:联机 Redo 日志切换后归档保存,支持备份后的恢复。
如果实例突然宕机,启动时通过 Redo 重做已提交变更,通过 Undo 回滚未提交变更。归档模式下,可以结合备份和归档日志做时间点恢复。
面试要强调:Redo 不是 SQL 文本日志,Undo 也不只是回滚日志,它还服务一致性读。
完整版教学
一、Redo 解决的是已提交变更能恢复
数据库不能每次提交都把所有脏数据块立刻写回数据文件,这样性能太差。Oracle 使用 Redo 记录数据块变更,只要提交时 redo 已安全落盘,即使数据块还没写回,实例崩溃后也能重做。
修改数据块 -> 产生 redo -> commit 时 LGWR 写 redo
实例崩溃 -> 启动时按 redo 重放已提交变更
记忆钩子:Redo 管“重做”,保证提交过的修改不会因为实例崩溃丢失。
二、Undo 解决的是回滚和一致性读
Undo 保存的是修改前的旧版本。事务回滚时,Oracle 根据 Undo 把数据恢复到修改前状态。另一个重要作用是一致性读:查询需要看到某个时间点的数据时,可以通过 Undo 构造旧版本。
例如事务 A 修改一行但未提交,事务 B 做普通查询,不应该看到 A 的未提交结果。Oracle 可以借助 Undo 还原 B 应该看到的旧值。
当前块:value = 200
Undo:value 原来是 100
旧快照查询 -> 通过 Undo 得到 100
所以 Undo 不只是“撤销日志”,也是多版本读一致性的基础。
三、联机 Redo 日志和归档日志的关系
联机 Redo 日志是数据库运行时循环写入的日志组。写满后会发生日志切换。如果数据库开启归档模式,切换出去的 Redo 日志会被 ARCn 进程复制成归档日志。
Redo Log Group 1 -> 写满 -> 切换
Redo Log Group 1 -> ARCn 归档为 archived log
归档日志的价值是支持恢复。只有联机 Redo 时,恢复窗口有限;有归档日志,就可以从备份恢复后继续应用归档,把数据库推进到指定时间点。
四、实例恢复如何使用 Redo 和 Undo
实例异常宕机后,内存中的脏块可能还没写回数据文件。重启时 Oracle 会做实例恢复。
恢复大致分两步:
Roll forward: 使用 Redo 重做变更
Roll back: 使用 Undo 回滚未提交事务
这样既保证已提交数据不丢,也保证未提交数据不会留下来。这个过程解释了为什么 LGWR 对提交非常关键。
五、归档模式影响备份恢复能力
非归档模式下,联机 Redo 被覆盖后就找不回历史变更,通常只能恢复到最近冷备份状态。归档模式下,可以用备份加归档日志做更完整恢复。
| 模式 | 优点 | 风险 |
|---|---|---|
| 非归档模式 | 管理简单,日志少 | 恢复能力弱 |
| 归档模式 | 支持在线备份和时间点恢复 | 归档空间要管理 |
生产数据库通常开启归档模式,并监控归档目录空间。归档空间满可能导致数据库无法继续正常写日志。
六、Redo、Undo 和业务日志不要混淆
Redo 记录的是数据库底层变更,不是业务审计日志;Undo 保存旧版本,也不是给业务报表查询历史的万能方案。
如果业务需要审计“谁改了订单金额、从多少改到多少”,仍要设计审计表或操作日志。不要指望直接读 Redo 或 Undo 解决业务审计。
数据库恢复:Redo/Undo
业务审计:audit_log/history_table
这是面试里区分数据库机制和业务设计的关键。
七、常见误区与追问
- 误区:Redo 记录的是 SQL 原文。 Redo 更接近数据块变更记录,不是业务 SQL 日志。
- 误区:Undo 只用于 rollback。 Undo 还用于一致性读,支持读到旧版本。
- 误区:开启归档就不用备份。 归档日志要和基础备份结合,单独归档不能替代备份。
- 追问:commit 时一定写数据文件吗? 不一定,关键是 redo 持久化,数据块可以稍后写回。
- 追问:归档目录满了会怎样? Redo 不能正常归档,可能影响日志切换和数据库写入。
- 追问:时间点恢复靠什么? 靠基础备份加归档日志和必要的联机 Redo。
八、面试中可以这样落地
回答恢复流程时可以说:事务修改先产生 Undo 和 Redo;提交时 LGWR 写 Redo;实例宕机后先用 Redo roll forward,再用 Undo 回滚未提交事务;介质恢复则需要备份和归档日志。
普通事务:Undo 保存旧值,Redo 保存变更
实例恢复:Redo 重做,Undo 回滚
介质恢复:备份 + 归档日志 + Redo
这个回答能覆盖事务、崩溃恢复和备份恢复三个层面。
九、加强记忆
Redo 负责重做,Undo 负责撤销和一致性读,归档日志负责把 Redo 历史保存下来用于恢复。提交安全靠 Redo 先落盘,不靠数据块立刻写回。面试时记住“Redo 保提交,Undo 保回滚和旧读,归档保恢复窗口”。