ora-19566 是数据库读到坏块后主动中止备份,非配置错误;应先查 v$database_block_corruption 定位坏块,再按 corruption_type 分类修复,set maxcorrupt 仅临时容忍但不修复。
ora-19566 不是备份配置错误,而是数据库在读到坏块后主动中止——它拒绝把损坏数据写进备份集。直接设 set maxcorrupt 只会让备份跑完,但坏块原封不动进备份,恢复时照样报 ora-01578。
先查 v$database_block_corruption,别急着进 RMAN 调参数
这个视图是唯一记录“已确认坏块”的地方,空结果不等于没坏块,但非空就一定得处理。
- 执行
SELECT * FROM v$database_block_corruption;,拿到FILE#、BLOCK#、CORRUPTION_TYPE -
CORRUPTION_TYPE常见值:CORRUPT(物理扇区损坏)、FRACTURED(块头尾校验不一致)、LOGICAL(索引键乱序、LOB 指针断裂) - 若返回多行,尤其连续
BLOCK#,说明不是孤立坏块,而是段级损坏,修复优先级更高 - 若视图为空但仍有
ORA-19566,补做RMAN> VALIDATE CHECK LOGICAL DATABASE;或用dbv手动扫文件
SET MAXCORRUPT 必须绑定具体数据文件,且只在当前 run 块内生效
它不是全局开关,也不是持久化配置,写错位置或范围就静默失效。
- 正确写法:
SET MAXCORRUPT FOR DATAFILE 4 TO 10;,必须放在run { ... }内部、BACKUP命令之前 - 如果坏块分布在多个文件(比如
FILE#显示 3、7、12 都有),得为每个文件单独设一次 - 设成 100 不代表“安全”,只代表你愿意容忍 100 个坏块被复制过去——这些坏块在恢复时依然会报
ORA-01578 - 错误写法如
SET MAXCORRUPT TO 10(语法不合法)或在BACKUP DATABASE前全局设置(无效)
定位坏块所属对象:用 DBA_EXTENTS 反查表/索引/LOB 段
知道文件和块号只是起点;不明确坏块属于哪个对象,修复就是盲操作。
- 执行
SELECT owner, segment_name, segment_type FROM dba_extents WHERE file_id = &F AND &B BETWEEN block_id AND block_id + blocks - 1;(&F和&B替换为上一步查到的值) - 若查不到结果,可能坏块落在空闲空间或系统段(如回滚段、数据字典),需结合
alert.log中的Corrupt Block Found行比对OBJN/OBJD - LOB 段坏块容易被忽略:普通
BACKUP DATABASE不校验 LOB 内容,必须显式加CHECK LOGICAL - 对疑似对象运行
ANALYZE TABLE xxx VALIDATE STRUCTURE CASCADE;能触发更细粒度逻辑校验,但会锁表,OLTP 环境慎用
修复比跳过更重要:物理坏块不能靠 MAXCORRUPT 解决
MAXCORRUPT 是临时创可贴,不是修复开关。物理坏块(CORRUPT、FRACTURED)必须从存储层入手。
-
FRACTURED或CORRUPT:本质是存储层问题(RAID 降级、磁盘扇区失效、ASM 磁盘亮红灯),必须先换硬件或重建阵列,再用RECOVER DATAFILE或BLOCKRECOVER恢复 -
LOGICAL且是索引:最安全快捷,直接DROP INDEX idx_name;+CREATE INDEX,无需停业务 -
LOGICAL且是表:优先尝试ALTER TABLE xxx MOVE;(会重建段并跳过坏块),但注意索引失效、LOB 存储属性重置等问题 -
EVENT 10231+CREATE TABLE AS SELECT抽出好数据,该事件在 19c PDB 模式下已失效(2026年5月6日)
真正麻烦的是 FRACTURED 块若位于数据文件头部——后续所有备份都可能反复触发 ORA-19566;不从存储层排查,只调 RMAN 参数,迟早撞上恢复失效的墙。











