rman的resync catalog不校验物理存在性,仅单向同步控制文件中v$archived_log记录(含已丢失但未标记expired的归档),故无法自动修复元数据不一致。
归档日志物理删除后,rman 不会自动感知或清理 catalog 中对应记录 —— 这会导致 list archivelog all 显示已不存在的日志、delete archivelog all 报错 ora-19606 或跳过实际缺失项,必须手动同步元数据。
为什么 resync catalog 不能自动修复归档日志元数据不一致
RMAN 的 resync catalog 命令只从控制文件读取当前已注册的归档日志信息(即 v$archived_log 中 status = 'A' 且未被 delete input 标记为已删的记录),它不会扫描磁盘路径去校验物理存在性。如果归档日志被 OS rm、find -delete 或第三方脚本直接删掉,控制文件里仍保留其记录(status 仍为 'A'),catalog 就会跟着“相信”它还在。
常见错误现象包括:
-
delete archivelog until time 'sysdate-7'实际没删任何文件,但返回 success -
list expired archivelog all为空,而list archivelog all却列出大量路径不存在的日志 - 执行
recover database时卡在某个归档日志,报错ORA-00308: cannot open archived log
先确认归档日志是否真的丢失:查控制文件 vs 磁盘
不要直接跑 resync。先定位哪些归档日志元数据和物理状态不匹配:
- 查控制文件中认为“存在”的归档:
select name, first_time, next_time, sequence#, deleted from v$archived_log where deleted='NO' and name is not null order by first_time; - 用
ls -l或find /path/to/arch -name "*.arc" -newermt "2026-04-12"对比真实文件是否存在 - 若某条记录的
name在磁盘上ls返回空,则它就是“幽灵归档”
注意:v$archived_log.deleted = 'YES' 表示 RMAN 已标记删除(比如执行过 delete archivelog),这类可安全忽略;重点盯 deleted = 'NO' 但文件不在磁盘上的。
手动清理 catalog 中的幽灵归档元数据
resync catalog 本身不解决这个问题 —— 它只是单向把控制文件内容刷进 catalog,而控制文件还没更新。真正要做的,是先让控制文件“忘记”那些已丢失的归档,再同步:
- 运行
CROSSCHECK ARCHIVELOG ALL:RMAN 会逐个检查v$archived_log.name对应路径,把找不到的标记为EXPIRED - 立刻跟
DELETE EXPIRED ARCHIVELOG ALL:从控制文件和 catalog 中**同时清除**这些失效记录 - 最后执行
RESYNC CATALOG:确保 catalog 和刚清理过的控制文件完全一致
这三步缺一不可。漏掉 CROSSCHECK,DELETE EXPIRED 就没东西可删;漏掉 RESYNC,catalog 里可能还残留旧快照。
预防下次再踩坑:归档清理必须走 RMAN,别碰文件系统
所有归档日志生命周期管理,必须通过 RMAN 控制,而不是 rm 或定时脚本清目录:
- 设置归档保留策略:
CONFIGURE ARCHIVELOG DELETION POLICY TO BACKED UP 2 TIMES TO DEVICE TYPE DISK; - 日常清理统一用:
DELETE ARCHIVELOG UNTIL TIME 'SYSDATE-3';或DELETE ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-2'; - 如果用了 FRA(快速恢复区),确保
db_recovery_file_dest_size足够,并依赖 Oracle 自动清理机制
一旦绕过 RMAN 直接删文件,就等于撕掉了元数据和物理文件之间的契约 —— 后续的 resync、restore、recover 都可能因元数据污染而行为异常,尤其是涉及 RECOVER TABLE 或 DG 备库同步时,幽灵归档会直接阻断应用日志流。











