ORA-19566是数据库读到坏块后主动中止备份的完整性保护机制,非备份失败;须先查v$database_block_corruption定位坏块,再依CORRUPT/FRACTURED/LOGICAL类型分物理修复(需硬件介入+恢复)或逻辑修复(如重建索引、ALTER TABLE MOVE),严禁盲目设SET MAXCORRUPT。
ora-19566 不是备份失败,是 rman 在读到坏块后主动中止——它拒绝把损坏数据写进备份集。直接设 set maxcorrupt 只会让备份跑完,但坏块原封不动进备份,恢复时照样报 ora-01578。
查 v$database_block_corruption 确认坏块位置,别跳步
这视图是唯一记录“已确认坏块”的地方,空结果不等于没坏块,但非空就一定得处理。
- 登录 SQL*Plus,执行
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扫文件
用 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 - 对疑似对象运行
ANALYZE TABLE xxx VALIDATE STRUCTURE CASCADE;可触发更细粒度逻辑校验,但会锁表,OLTP 环境慎用 - LOB 段坏块容易被忽略:普通
BACKUP DATABASE不校验 LOB 内容,必须显式加CHECK LOGICAL
按坏块类型分路径修复,别一概重建索引
物理坏块和逻辑坏块的修复成本、风险、依赖条件完全不同,混用方案等于埋雷。
-
FRACTURED或CORRUPT:本质是存储层问题。RAID 降级、磁盘扇区失效、ASM 磁盘亮红灯——必须先换硬件或重建阵列,再用RECOVER DATAFILE或BLOCKRECOVER恢复;DBMS_REPAIR只能跳过,不能修复 -
LOGICAL且是索引:最安全快捷。直接DROP INDEX idx_name;+CREATE INDEX,无需停业务 -
LOGICAL且是表:优先尝试ALTER TABLE xxx MOVE;(会重建段并跳过坏块),但需注意索引失效、LOB 存储属性重置等问题;若不可行,再考虑EVENT 10231+CREATE TABLE AS SELECT抽出好数据(该事件在 19c PDB 模式下已失效)
SET MAXCORRUPT 是临时创可贴,必须限定到具体数据文件
它只在一个 run 块内生效,且必须绑定具体数据文件,设了也不代表安全。
- 正确写法:
SET MAXCORRUPT FOR DATAFILE 4 TO 5;,必须放在backup命令之前、同一run块内 - 漏掉
FOR DATAFILE或写错文件号会静默失效;如果坏块分布在多个文件(比如FILE#显示 3、7、12 都有),得为每个文件单独设一次 - 数值不是“容忍度”,而是“允许跳过的坏块上限”;设成 100 不等于修好了,只是把 100 个坏块复制进了备份集
- 仅建议用于:已确认坏块不影响业务核心路径、且修复窗口未到,需先保备份链不断;用完立即还原为 0,并跟踪修复
真正麻烦的是连续坏块或跨段坏块——这类情况往往意味着底层存储已开始劣化,v$database_block_corruption 只是冰山一角,得立刻查 asmcmd lsdg、smartctl 或存储阵列健康状态,而不是只盯着数据库层修。


















