Oracle 实例恢复与崩溃恢复
Oracle 实例恢复与崩溃恢复
适用版本:Oracle Database 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07
1. 概述
实例恢复(Instance Recovery) 是数据库异常关闭后,启动时自动将数据库恢复到一致状态的过程[1]。
触发场景:
SHUTDOWN ABORT- 实例崩溃(断电、OOM、进程被杀)
- 节点故障后 RAC 重启动
- 实例异常终止后 STARTUP
核心机制:利用 Redo Log 重做未落盘的修改,利用 Undo 回滚未提交事务。
2. 实例恢复的必要性
2.1 为什么需要恢复
Oracle 的写策略:
- LGWR 先写 Redo Log(commit 时)
- DBWn 异步写数据块(延迟写)
因此存在时间差:
T1: 事务 COMMIT → LGWR 写 Redo Log
T2: 实例崩溃(DBWn 还未写数据块)
T3: 重启实例
→ 数据文件中没有该事务的修改
→ Redo Log 中有该事务的记录
→ 需要 Redo 重做
2.2 一致性状态判断
-- 启动到 MOUNT 状态查询
STARTUP MOUNT;
-- 检查每个数据文件的 SCN
SELECT
f.file#,
f.name,
f.checkpoint_change# AS file_ckpt_scn,
h.checkpoint_change# AS header_ckpt_scn,
f.last_change# AS stop_scn
FROM v$datafile f
JOIN v$datafile_header h ON f.file# = h.file#;
-- 正常关闭:
-- stop_scn = file_ckpt_scn = header_ckpt_scn
-- 不需要恢复
-- 异常关闭:
-- stop_scn = NULL(或与 file_ckpt_scn 不等)
-- 需要实例恢复
3. 实例恢复的两个阶段
3.1 前滚(Roll Forward / Cache Recovery)
从 Redo Log 中重做检查点之后的所有变更,包括已提交和未提交的事务[1][2]:
Redo Log:
+---------+---------+---------+---------+---------+
| Redo 1 | Redo 2 | Redo 3 | Redo 4 | Redo 5 |
+---------+---------+---------+---------+---------+
↑
Checkpoint RBA
[--------- 已落盘 ---------][------ 前滚范围 ------]
前滚过程:
1. 从 Checkpoint RBA 开始读 Redo
2. 对每条 Redo 记录:
a. 找到对应数据块
b. 比较数据块 SCN 与 Redo SCN
c. 若 Redo SCN > 块 SCN,应用 Redo
d. 否则跳过
3. 直到 Redo 末尾
3.2 打开数据库
前滚完成后,数据库达到一致状态,可以打开供用户访问。
3.3 回滚(Roll Back / Transaction Recovery)
打开数据库后,后台 SMON 异步回滚未提交事务[2]:
Undo 段中记录了未提交事务的旧值
回滚过程:
1. 扫描 Undo 段,找出未提交的事务
2. 对每个事务:
a. 从 Undo 记录中取旧值
b. 将数据块恢复到旧值
3. 标记事务为 ROLLED BACK
注意:回滚是异步进行的,用户可继续访问数据库,但访问未提交事务修改的数据时需要等待回滚完成。
4. 实例恢复详细流程
1. STARTUP NOMOUNT
- 读取参数文件
- 分配 SGA
- 启动后台进程
2. STARTUP MOUNT
- 读取控制文件
- 检查数据文件状态
- 发现 stop_scn = NULL,需要恢复
3. 前滚阶段
- SMON 读取 Redo Log
- 从 Checkpoint RBA 开始重做
- 并行恢复(PARALLEL_RECOVERY)
- 推进数据文件 SCN
4. 打开数据库
- 数据文件 SCN 与控制文件一致
- 打开数据文件
- 用户可访问
5. 回滚阶段(SMON 异步)
- 扫描 Undo 段
- 回滚未提交事务
- 释放事务锁
6. 完成
- 数据库完全可用
警报日志示例:
Sun Jul 21 10:23:15 2026
Starting ORACLE instance (normal)
...
ALTER DATABASE MOUNT
Successful mount of redo thread 1
Database mounted in Exclusive Mode
Sun Jul 21 10:23:25 2026
ALTER DATABASE OPEN
Beginning crash recovery of 1 threads
parallel recovery started with 4 processes
Started redo scan
Completed redo scan
read 512 KB redo, 152 data blocks need recovery
Started redo application at
Thread 1: logseq 245, block 1024
Recovery of Online Redo Log: Thread 1 Group 2 Seq 245 Reading mem 0
Completed redo application of 0.05MB
Crash recovery applied 152 redo records and 152 data blocks
Completed crash recovery at
Thread 1: logseq 245, block 1320, scn 1234567890
48 data blocks read, 48 data blocks written, 152 redo records read
Database opened.
5. RAC 中的实例恢复
RAC 中某节点崩溃后,幸存节点自动执行实例恢复[3]:
节点 1 崩溃 → 节点 2 检测到 → 节点 2 执行实例恢复
RAC 实例恢复特点:
- 由幸存节点的 SMON 执行
- 需要读取崩溃节点的 Thread(Redo Log)
- Cache Fusion 锁资源需要重整
- 用户感知:极短暂停顿后继续可用
6. 实例恢复 vs 介质恢复
| 维度 | 实例恢复 | 介质恢复 |
|---|---|---|
| 触发 | 异常重启 | 数据文件损坏/丢失 |
| 数据来源 | 在线 Redo Log | 归档 Redo Log + 在线 Redo Log |
| 执行者 | SMON 自动 | DBA 手动(RMAN/SQL*Plus) |
| 是否需要备份 | 否 | 是(除非仅 Redo 丢失) |
| 恢复时间 | 秒-分钟 | 分钟-小时 |
7. MTTR(Mean Time To Recover)
MTTR = 实例恢复时间,受 FAST_START_MTTR_TARGET 参数控制:
SHOW PARAMETER fast_start_mttr_target;
-- 设置目标 MTTR 为 60 秒
ALTER SYSTEM SET fast_start_mttr_target=60 SCOPE=BOTH;
MTTR 估算:
SELECT
recovery_estimated_ios,
actual_redo_blks,
target_redo_blks,
fast_start_mttr_target_redo_blks
FROM v$instance_recovery;
详细内容见:Oracle 检查点 Checkpoint 机制详解。
8. 加速实例恢复
8.1 调整 MTTR 目标
-- OLTP 推荐 60-120 秒
ALTER SYSTEM SET fast_start_mttr_target=60 SCOPE=BOTH;
8.2 并行恢复
-- 启用并行恢复
ALTER SYSTEM SET recovery_parallelism=4 SCOPE=SPFILE;
-- 或使用并行度参数
ALTER SYSTEM SET parallel_recovery_stopat=600 SCOPE=SPFILE;
-- 重启生效
SHUTDOWN IMMEDIATE;
STARTUP;
8.3 增加 DBWn 进程
ALTER SYSTEM SET db_writer_processes=4 SCOPE=SPFILE;
8.4 优化 Redo Log
-- 合适的 Redo Log 大小,避免频繁切换
SELECT group#, bytes/1024/1024 AS mb, status FROM v$log;
-- 推荐:单组大小让日志切换间隔 15-30 分钟
9. 实例恢复监控
9.1 实时监控
-- 查看恢复进度(恢复过程中)
SELECT
sid,
serial#,
program,
event,
seconds_in_wait
FROM v$session
WHERE program LIKE '%RECO%' OR program LIKE '%SMON%';
9.2 历史恢复信息
-- 查看最近恢复信息
SELECT
startup_time,
logins,
status,
archiver,
parallel,
thread#
FROM v$instance;
-- 警报日志检查
-- grep "crash recovery" alert_orcl.log
9.3 检查回滚进度
-- 查看待回滚事务
SELECT
local_tran_id,
state,
mixed
FROM dba_2pc_pending
WHERE state <> 'forced commit';
-- 查看回滚进度(10g+)
SELECT
usn,
state,
undoblocksdone,
undoblockstotal
FROM v$fast_start_transactions;
-- 进度百分比
SELECT
ROUND(SUM(undoblocksdone)/NULLIF(SUM(undoblockstotal),0)*100, 2) AS pct
FROM v$fast_start_transactions;
10. 常见坑与排错
10.1 恢复过程中无法连接
现象:STARTUP 后无法登录,提示数据库未打开。
澄清:实例恢复期间数据库处于 MOUNT 状态,未 OPEN。
处理:等待恢复完成,监控警报日志。
10.2 ORA-01113: file needs media recovery
现象:
ORA-01113: file 1 needs media recovery
ORA-01110: data file 1: '/u01/oradata/orcl/system01.dbf'
原因:实例恢复无法完成(如 Redo Log 损坏)。
修复:
-- 启动到 MOUNT
STARTUP MOUNT;
-- 使用 RMAN 介质恢复
RMAN> RECOVER DATABASE;
-- 完成后打开
SQL> ALTER DATABASE OPEN;
10.3 ORA-01589: must use RESETLOGS
现象:
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open
原因:不完全恢复后需要 RESETLOGS。
修复:
-- 如果是不完全恢复
ALTER DATABASE OPEN RESETLOGS;
-- 备份恢复后
ALTER DATABASE OPEN NORESETLOGS;
10.4 回滚耗时过长
现象:数据库 OPEN 后,应用响应慢,发现 SMON 在回滚大量事务。
排查:
SELECT
pid, state, undoblocksdone, undoblockstotal,
ROUND(undoblocksdone/NULLIF(undoblockstotal,0)*100, 2) AS pct
FROM v$fast_start_transactions;
加速:
-- 增加并行回滚
ALTER SYSTEM SET fast_start_parallel_rollback=HIGH SCOPE=BOTH;
-- HIGH = 4×CPU_COUNT 并行度
10.5 RAC 节点恢复失败
现象:节点 1 崩溃后,节点 2 无法执行实例恢复。
原因:节点 1 的 Redo Thread 未被关闭。
修复:
-- 在幸存节点执行
ALTER DATABASE DISABLE THREAD 1;
-- 后续根据需要重新启用
11. 最佳实践
- 设置合理的 FAST_START_MTTR_TARGET:60-120 秒
- 避免 SHUTDOWN ABORT:除非紧急情况
- ABORT 后立即备份:避免后续故障叠加
- 启用并行恢复:
recovery_parallelism参数 - 合理规划 Redo Log:大小、组数、多路复用
- 监控 MTTR:定期检查
v$instance_recovery - 关键业务启用 RAC:单节点故障自动切换
- 定期灾备演练:验证恢复流程
12. 参考资料
[1] Oracle Database Concepts 19c, “Instance Recovery” https://docs.oracle.com/en/database/oracle/oracle-database/19/cncpt/instance-recovery.html
[2] Oracle Database Administrator’s Guide 19c, “Performing Instance Recovery” https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/instance-and-media-recovery.html
[3] Oracle Real Application Clusters Administration and Deployment Guide 19c https://docs.oracle.com/en/database/oracle/oracle-database/19/racad/
[4] Oracle Support Note 1424962.1, “Crash Recovery Internals” https://support.oracle.com/epmos/faces/DocumentDisplay?id=1424962.1