RMAN不能直接修复逻辑坏块,只能用备份中干净副本覆盖损坏块,前提是备份时该块未被写坏;需结合ORA-26040、SYSTEM/UNDO表空间位置、V$视图状态等判断是否可恢复,并执行VALIDATE、确认备份可用性、确保归档模式与数据文件ONLINE后,再运行RECOVER命令并清空buffer cache。

RMAN 不能直接“修复”逻辑坏块,它只能定位损坏块并用备份中干净的副本覆盖——前提是那个块在备份里没被写坏。遇到 ORA-01578 报错后,别急着重建表或跳过数据,先确认是否真能靠 RMAN 拉回来。
怎么确认坏块是 RMAN 可恢复的类型
不是所有 ORA-01578 都能用 blockrecover 解决。关键看错误是否伴随 ORA-26040(NOLOGGING 导致的 soft corruption),或者是否发生在 SYSTEM 表空间底层对象(如 OBJ$、UNDO$)上。
- 如果报错同时含
ORA-26040:说明是 NOLOGGING 操作导致,RMAN 备份里大概率也存了坏块,blockrecover会失败,得走增量备份 + 主库传输路径 - 如果
V$NONLOGGED_BLOCK有记录:说明近期有 NOLOGGING 写入,风险高,VALIDATE CHECK LOGICAL可能漏检 - 如果坏块在 SYSTEM 或 UNDO 表空间,且数据库无法 OPEN:RMAN 来不及介入,得先用
_allow_resetlogs_corruption或 BBED 应急,再考虑恢复 - 单纯
ORA-01578+ORA-01110,且V$DATABASE_BLOCK_CORRUPTION有记录:大概率可 recover
执行 blockrecover 前必须做的三件事
blockrecover 不是拿来就跑的命令,漏掉任一环节都会报 RMAN-06023: no backup or copy of datafile found 或静默失败。
- 先跑
BACKUP VALIDATE CHECK LOGICAL DATAFILE <code>file#:只校验不写备份,触发坏块登记到V$DATABASE_BLOCK_CORRUPTION - 查
LIST BACKUP OF DATAFILE <code>file#:确认该文件最近一次全备/增量备时间,且备份集状态为AVAILABLE - 确保数据库处于归档模式,且目标数据文件 ONLINE:RMAN 不支持对 OFFLINE 数据文件做块恢复;若文件已 OFFLINE,先
ALTER DATABASE DATAFILE <code>file#ONLINE
blockrecover 的实际写法和常见坑
语法看着简单,但参数组合和上下文影响结果。以下写法按优先级排列:
- 单块修复:
RECOVER DATAFILE <code>file#BLOCKblock#—— 注意是RECOVER,不是RESTORE;RMAN 自动从备份拉块,不重建整个文件 - 多块修复:
RECOVER DATAFILE <code>file#BLOCKblock1,block2,block3—— 块号必须同属一个文件,不能跨文件逗号拼接 - 批量修复所有已知坏块:
RECOVER CORRUPTION LIST—— 依赖V$DATABASE_BLOCK_CORRUPTION实时内容,执行前别手动清空该视图 - 误写成
RESTORE DATAFILE <code>file#BLOCKblock#:报错RMAN-00571,因为 RMAN 没有块级 restore 命令 - 没加
CHECK LOGICAL就跑VALIDATE:可能漏掉逻辑坏块,V$DATABASE_BLOCK_CORRUPTION为空,但应用仍报ORA-00600 [kdxlin: invalid rowid]
为什么有时 blockrecover 成功了,查询还是报 ORA-01578
最常被忽略的一点:坏块可能还在 buffer cache 里。RMAN 恢复的是磁盘块,但 Oracle 读取时优先走内存,如果旧的坏块镜像没被淘汰,下次 SELECT 还会撞上它。
- 执行完
RECOVER后,立刻运行ALTER SYSTEM FLUSH BUFFER_CACHE—— 强制清空 buffer,避免缓存污染 - 检查
V$BH视图:SELECT * FROM V$BH WHERE FILE# = <code>file#AND BLOCK# =block#AND STATUS != 'free',确认坏块已不在 cache 中 - 如果对象启用了
FORCE LOGGING,但某次操作绕过了(比如用DISABLE_ARCHIVE_LOGGING:Yimpdp),那即使 recover 了,后续日志应用仍可能重刷出坏块
真正卡住人的地方往往不是命令输错,而是没意识到 RMAN 的 recover 是“覆盖磁盘块 + 清 buffer cache”的组合动作,少一步,问题就还在原地。


















