数据库卡在mount状态且报ora-01578或ora-00600(2000–8000),说明坏块已阻塞介质恢复;此时不能直接restore datafile,因其会覆盖增量变更导致数据丢失,而应优先用blockrecover精准修复坏块并跳过恢复中断。
数据库卡在 mount 状态、报 ora-01578 或 ora-00600(参数在 2000–8000 范围),且 recover database 失败,说明坏块已阻碍介质恢复流程——这时不能硬启,也不能直接 restore datafile,必须先用 blockrecover 绕过坏块完成恢复链。
坏块阻塞 recover 时,为什么不能直接 restore datafile?
当 RECOVER DATABASE 报错中断(如 RMAN-06026 / RMAN-06023),常见原因是归档日志或备份片缺失,但更关键的是:RMAN 在应用归档时读到坏块就直接退出。此时若执行 RESTORE DATAFILE,会把整个文件拉回上次全备时间点,丢失所有增量变更,等于“用旧数据覆盖新数据”。
真正该做的是让恢复跳过坏块本身,只修复它——BLOCKRECOVER 正是为此设计的,它不依赖完整数据文件备份,只要归档日志里有该块的前镜像(before image)和重做记录,就能重建单个块。
- 确认归档是否完整:
LIST ARCHIVELOG ALL;查看目标时间段内归档是否存在且未被DELETE INPUT清掉 - 检查坏块是否在 SYSTEM/UNDO 表空间:这类块必须在 MOUNT 状态下修复,且需确保其他实例已关闭(RAC 中只留一个实例启动)
- 如果坏块位于用户表空间,且数据库能成功
STARTUP MOUNT,就可直接进 RMAN 执行BLOCKRECOVER
RMAN BLOCKRECOVER 在 MOUNT 状态下的实操要点
进入 MOUNT 状态后,RMAN 可定位并修复坏块,但操作逻辑和 OPEN 状态不同:
- 先查坏块位置:
SELECT file#, block#, corruption_type FROM v$database_block_corruption;(注意:MOUNT 下该视图可能为空,需从告警日志或 trace 文件提取file #和block #) - 若损坏在 UNDO 表空间,必须先屏蔽问题回滚段:
ALTER SYSTEM SET "_corrupted_rollback_segments"=("_SYSSMU1_","_SYSSMU2_") SCOPE=SPFILE;,再重启至 MOUNT - 执行修复:
BLOCKRECOVER DATAFILE 4 BLOCK 133;(支持批量,如BLOCKRECOVER DATAFILE 4 BLOCK 133,134,135;) - 修复成功后,
ALTER DATABASE OPEN;—— 若仍报错,说明还有未发现的坏块,需再次VALIDATE CHECK LOGICAL DATABASE
RAC 环境下 BLOCKRECOVER 后必须 flush buffer cache
RAC 中 BLOCKRECOVER 只作用于当前连接的实例,修复后的块只写入该实例的 buffer cache;其他实例缓存中仍保留旧的坏块镜像,下次读取时会再次触发 ORA-01578。
- 修复完成后,在每个已启动的实例上手动执行:
ALTER SYSTEM FLUSH BUFFER_CACHE; - 不要依赖自动同步,RAC 不保证跨实例 buffer cache 一致性
- 若某实例处于 QUIESCED 或 SUSPEND 状态,需先唤醒再执行 flush,否则该实例后续仍可能报错
- 验证是否生效:在各实例上查
v$bh,确认对应file#/block#的status不再是cr或xcu(表示已刷新)
BLOCKRECOVER 失败后最易忽略的三个检查点
当 BLOCKRECOVER 报 RMAN-06026 或 RMAN-06023,除了归档缺失,以下三点常被跳过:
-
DB_BLOCK_CHECKSUM被设为NONE:这会导致 DBWR 不写 checksum,读取时无法校验,但 RMAN 块恢复仍依赖归档中的逻辑一致性,需确认参数值为TYPICAL或FULL - ASM 磁盘组
ASM_POWER_LIMIT过低(默认为 1):修复过程涉及大量 ASM extent 操作,值太小会导致超时中断,建议临时调至 5–10 - 损坏块属于 LOBSEGMENT:LOB 块结构特殊,
BLOCKRECOVER可能无法定位其 chunk,此时需改用DBMS_REPAIR标记段并导出有效数据
坏块修复不是“执行一条命令就完事”,尤其是阻塞启动的场景——每一步都得确认上下文是否干净:归档链、实例状态、参数配置、缓存残留。漏掉任意一环,都会让数据库在 OPEN 时再次崩溃。











