adg自动修复在ora-01578报错时未必触发,需满足备库启用实时查询、无应用延迟、主备文件号一致等条件;未见alert log中“replaced from physical standby”记录即表明本次未成功修复。
oracle 12c adg 物理备库本身不修复主库坏块,但主库在访问坏块时,可自动从同步的物理备库拉取干净副本 —— 前提是备库必须处于实时查询(real-time query)模式且与主库完全同步。
ORA-01578 报错时,ADG 自动修复到底触发没?
报错本身不等于自动修复失败,而是说明“主库读到了坏块,且未成功从备库获取替代块”。常见原因包括:
- 备库未启用
REAL-TIME QUERY:执行SELECT DATABASE_ROLE, OPEN_MODE FROM V$DATABASE;,确认返回PHYSICAL STANDBY和READ ONLY WITH APPLY - 备库应用延迟(
APPLY LAG> 0):查V$DATAGUARD_STATS中apply lag字段,若值非零(如+00 00:02:15),则备库尚未应用到主库出错时刻的归档日志,无法提供该块的干净版本 - 主库未启用自动修复开关:需设置初始化参数
DB_LOST_WRITE_PROTECT=TYPICAL(仅影响丢失写检测)或确保_corrupted_rollback_segments等隐含参数未干扰机制 —— 但真正控制自动拉取的是底层逻辑,无需显式开启某开关 - 坏块位于备库也损坏的区域(如共享存储故障波及双端):此时两边 checksum 都校验失败,自动修复无源可溯
验证坏块是否被 ADG 自动修复过
不能只看 SQL 是否报错,要查内部修复记录:
- 主库上执行:
SELECT * FROM V$CORRUPTED_BLOCK;—— 若为空,不代表没坏块,只代表当前未被标记为已知坏块;V$DATABASE_BLOCK_CORRUPTION才是 RMAN VALIDATE 后的权威视图 - 更关键的是查
V$MANAGED_STANDBY和告警日志:搜索关键字auto repair或replaced block。Oracle 在完成自动替换后,会在主库 alert log 写入类似:Corrupt block (file 4, block 133) replaced from physical standby database - 如果 alert log 没有该记录,而你又确认备库状态正常,则大概率本次访问未触发修复 —— 可能因会话使用了 direct path read、或块被缓存在 buffer cache 中未重新读取
RMAN BLOCKRECOVER 跟 ADG 自动修复是什么关系?
两者完全独立,适用场景不同:
-
BLOCKRECOVER是 DBA 主动发起的、基于备份的**精确块级恢复**,依赖 RMAN 备份集或镜像拷贝,不依赖备库,适用于无备库或备库也坏的情况 - ADG 自动修复是 Oracle 内核在**运行时透明完成**的块级“热替换”,不产生归档日志、不修改 SCN、不需 DBA 干预,但只在主库读取坏块那一刻才尝试 —— 它不是恢复手段,而是容错机制
- 如果
BLOCKRECOVER成功执行,它会清除V$DATABASE_BLOCK_CORRUPTION中对应记录,并让该块恢复正常;而 ADG 自动修复不会清除该视图中的记录(除非后续 RMAN VALIDATE 再次扫描确认已修复) - 注意:
BLOCKRECOVER不能用于修复备库自身的坏块 —— 备库上运行该命令会报错ORA-19598: block media recovery not supported on a standby database
为什么灾备环境没自动修复?最常忽略的三点
很多 DBA 查完角色和模式就放弃排查,其实以下三点才是高频盲区:
- 主库的
LOG_ARCHIVE_DEST_n参数中,指向备库的那条配置,必须包含SYNC或REAL_TIME APPLY属性,否则即使备库开 RTQ,主库也不认为它是“可信赖的实时源” - 备库的
STANDBY_FILE_MANAGEMENT设为AUTO是基础,但若主库新增数据文件后未触发自动传播,备库缺失该文件 —— 则对应文件号上的坏块根本无法从备库获取 - 主库发生坏块的文件,其
FILE#在备库上必须严格一致(即不能是通过CREATE CONTROLFILE重建过控制文件导致 file_id 重排)。一旦 file_id 错位,主库请求 “file 4, block 133”,备库按自己 file 4 去找,实际对应的是另一文件,自然找不到干净块
自动修复机制只在坏块被首次读取且满足全部条件时起效;一旦跳过,后续同会话可能继续读缓存脏块,掩盖问题。真要确认是否修好,别信日志里“没报错”,得用 RMAN BACKUP VALIDATE CHECK LOGICAL DATABASE 再扫一遍,再查 V$DATABASE_BLOCK_CORRUPTION —— 空了,才算落地。











