ora-19566本质是rman因检测到坏块且maxcorrupt=0而主动中止备份,属完整性保护机制;须先查v$database_block_corruption定位坏块,再分析对象、验证并修复,而非盲目设maxcorrupt。
ora-19566 错误本质是“拒绝带病备份”,不是备份失败本身
报错 ora-19566: exceeded limit of 0 corrupt blocks 的核心含义很直白:rman 在扫描数据文件时,发现了坏块(物理或逻辑),而当前允许的坏块数上限是 0——它宁可中断也不愿把损坏数据写进备份集。这不是磁盘写不进去、通道配错了、路径没权限那种“操作失败”,而是数据库主动触发的完整性守门行为。一旦出现,说明坏块已真实存在且未被处理,绕过它等于埋下恢复失效的雷。
定位坏块必须先查 v$database_block_corruption,别急着调 maxcorrupt
直接在 RMAN 里执行 set maxcorrupt for datafile 4 to 100 是最常见也最危险的“速效解”。真正该做的第一步,是确认坏块在哪、影响什么对象:
- 运行
SELECT * FROM v$database_block_corruption;,拿到FILE#、BLOCK#和CORRUPTION_TYPE - 用
DBA_EXTENTS反查对象:SELECT segment_name, segment_type, owner FROM dba_extents WHERE file_id = &F AND &B BETWEEN block_id AND block_id + blocks - 1;(&F和&B替换为上一步查到的值) - 配合
dbv验证:dbv file=/path/to/datafile.dbf blocksize=8192,看是否输出Fractured block或校验值不匹配
跳过这步就设 maxcorrupt,等于医生没做CT就开止痛药——症状压下去了,但肿瘤还在长。
set maxcorrupt 只能临时用,且必须限定到具体数据文件
maxcorrupt 是 RMAN session 级参数,不是全局配置,也不会持久化。它的作用范围极窄:只对当前 run 块中后续的 backup 操作生效,且必须绑定到某个 datafile。错误写法如 set maxcorrupt to 10(语法不合法)或在 backup database 前全局设置(无效)。
- 正确写法必须带目标文件:
set maxcorrupt for datafile 4 to 10; - 必须放在
run { ... }内部、backup命令之前 - 如果坏块分布在多个文件(比如
FILE#显示 3、7、12 都有),得为每个文件单独设一次 - 设成
100不代表“安全”,只代表你愿意容忍 100 个坏块被复制过去——这些坏块在恢复时依然会报ORA-01578
修复比容忍更重要,逻辑坏块优先重建索引,表坏块慎用 10231 事件
发现坏块后,maxcorrupt 只是让备份跑完的“创可贴”,修复才是根治。逻辑坏块(如索引结构错乱)成本低、风险小;物理坏块(如磁盘扇区损坏)则需硬件介入。
- 如果是索引坏块,直接
DROP INDEX idx_name; CREATE INDEX idx_name ON ...;即可,无需停业务 - 如果是表段坏块且有 RMAN 备份,优先用
blockrecover datafile 4 block 51896;(比全量恢复快得多) - 若无备份又必须抢救数据,启用
ALTER SYSTEM SET EVENTS '10231 trace name context forever, level 10';后用CREATE TABLE tab_new AS SELECT * FROM tab_old;跳过坏块导出可用行——但该事件在 Oracle 12c+ 已不推荐,且无法处理 LOB 坏块 - LOB 坏块需单独清理:
UPDATE tab SET lob_col = empty_blob() WHERE rowid IN (SELECT rowid FROM tab WHERE dbms_lob.getlength(lob_col) > 0 AND rownum = 1);(需结合实际定位)
真正棘手的是坏块出现在系统表空间(如 SYSTEM 或 SYSAUX)——这时候不能简单重建对象,得结合 DBMS_REPAIR 或联系 Oracle 支持。别低估它:一个坏块卡在数据字典里,可能让整个 expdp 或 DDL 都失败。










