ORA-19566报错本质是RMAN因检测到坏块且maxcorrupt=0而主动中止备份,属完整性保护机制;须先查v$database_block_corruption定位坏块,再分析对象、验证并修复,而非盲目设maxcorrupt。

set maxcorrupt 能跳过坏块,但只对 backup 有效
Oracle RMAN 默认遇到坏块会中止备份,并报 ORA-19566(超出损坏块容忍阈值)。想让备份继续,必须显式告诉 RMAN:“这个数据文件里允许最多 N 个坏块,别拦我”。这靠的是 set maxcorrupt for datafile 命令,它只影响后续的 backup 操作,对 restore 或 recover 完全无效。
常见错误是把它和 blockrecover 混用,或者误以为设了就能自动修复——它不修复、不跳过恢复过程、也不影响数据库运行时的读取行为,只是让备份“睁一只眼闭一只眼”。
-
set maxcorrupt必须在run块内、backup命令之前执行 - 数值不能为 0;设为 1 表示最多容忍 1 个坏块,设为 10 就是 10 个
- 若实际坏块数超过设定值,备份仍会失败,报
ORA-19566 - 该设置只对当前
run块生效,不持久化,下次备份需重设
backup ... skip inaccessible 是另一回事,别混淆
skip inaccessible 看起来像“跳过损坏”,但它跳过的根本不是坏块,而是**整个不可访问的文件**——比如文件权限丢失、路径不存在、磁盘离线或文件被 rm -f 删除后控制文件还没刷新。RMAN 发现文件 open 失败,就直接跳过它,连块校验都不做。
它和坏块无关:一个文件可能完全可读,但内部有几十个坏块,skip inaccessible 对它毫无作用;反过来,一个文件只是路径错了,哪怕内容完好,加了这个参数就会被跳过。
- 典型使用场景:
backup database skip inaccessible,用于灾备库归档日志路径不一致、或临时下线了某个非关键表空间文件 - 它不会改变备份集内容结构,也不会降低备份一致性保障等级
- 若你真正面对的是坏块,加这个参数毫无意义,反而可能掩盖真实问题
坏块太多时,backup 仍可能失败的三个隐藏原因
即使设了 set maxcorrupt,备份还是中断?大概率掉进了这三个坑:
- 控制文件里记录的该数据文件状态是
OFFLINE或RECOVER,RMAN 直接拒绝备份——先查v$datafile_header.status,必要时alter database datafile n online - 坏块集中在数据字典对象(如
sys.obj$)上,RMAN 在构建备份元数据阶段就读取失败,此时maxcorrupt还没起效——这种得先用dbms_repair标记跳过,或导出逻辑数据 - 使用了压缩备份(
as compressed backupset),而坏块导致压缩流校验失败,RMAN 会抛ORA-19501——换用非压缩方式再试
真正要“跳过坏块”恢复数据,得换思路
如果目标不是“把备份做出来”,而是“把还能读的数据抢救出来”,set maxcorrupt 就只是个临时掩耳盗铃的手段。更务实的做法是:
- 用
dbv file=/path/to/datafile.dbf定位具体坏块位置和数量 - 对非核心表,用
expdp加exclude=table_data:"IN (SELECT ...)"跳过含坏块的分区 - 对关键表,启用事件
alter system set events '10231 trace name context forever, level 10',让全表扫描跳过坏块(仅限 SELECT,DML 仍报错) - 最后考虑
blockrecover datafile n block m——但这要求你有包含该块的完整备份,且坏块数不能太多,否则效率极低
坏块不是开关,是症状。设 maxcorrupt 能让备份跑通,但不会让损坏消失;恢复链路上任何一环(controlfile、archivelog、SCN 对齐)出问题,都可能让这份“带病备份”变成废片。


















