因为oracle不自动扫描归档目录新增文件,手动拷贝归档后未通过rman catalog注册到控制文件,导致recover无法识别和应用;必须先校验文件有效性,再执行catalog命令将归档路径写入控制文件,否则list archivelog不可见、applied仍为no且同步卡住。
备库归档被删后,recover 不报错但同步卡住,为什么?
因为 oracle 不会自动扫描归档目录新增文件;即使你把主库备份里的 1_123_987654321.dbf 手动 cp 到备库的 /u01/app/oracle/fast_recovery_area/orcl/archivelog/,list archivelog all 仍看不到它,recover managed standby database 也不会用——控制文件里没这条记录。
常见错误现象:
-
V$ARCHIVED_LOG中最新SEQUENCE#停在一个月前,APPLIED = 'NO' -
SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP;返回非空结果(比如THREAD#=1, LOW_SEQUENCE#=123, HIGH_SEQUENCE#=125) - 手动执行
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT;后,状态仍是MANAGED STANDBY RECOVERY,但日志不再前进
RMAN 恢复归档日志必须分两步:解压 + CATALOG
不能直接把压缩包里的归档解压到归档路径下就完事。RMAN 只认控制文件里注册过的归档,不认文件系统里“看起来像”的文件。
实操建议:
- 先解压到临时目录,例如:
tar -xvf arch_bkup_20260309.tar -C /tmp/arch_restored/ - 启动 RMAN 连接目标库:
rman TARGET /(不需要恢复目录) - 执行注册命令:
CATALOG START WITH '/tmp/arch_restored/';—— 它会递归扫描所有子目录下的有效归档并写入控制文件 - 确认注册成功:
LIST ARCHIVELOG FROM SEQUENCE 123;应看到STATUS = A(Available) - 若报错
ORA-19870: error while restoring backup piece ... already cataloged,说明控制文件中已有同名归档记录,可加FORCE强制重试:CATALOG FORCE ARCHIVELOG '/tmp/arch_restored/1_123_987654321.dbf';
注册前务必校验归档文件有效性
损坏或截断的归档文件注册进去后,后续 RECOVER 会报 ORA-00317: file type 0 in header is not log file 或 ORA-00334: archived log,导致恢复中断。
快速验证方法:
- 检查文件头是否含 Oracle 归档标识:
strings /tmp/arch_restored/1_123_987654321.dbf | head -5 | grep -i "archived log" - 确认文件大小合理(一般 ≥ 1MB,极小值如 24KB 多为损坏)
- 用
tar -tvf arch_bkup_20260309.tar | grep 1_123确保压缩包内该文件未被截断
绕过缺失归档最稳妥的是 SET UNTIL SCN,不是 SEQUENCE
如果部分归档确实无法找回(比如备份已覆盖、磁带丢失),又必须推进同步,SET UNTIL SEQUENCE 会失败——只要缺了 123,哪怕 124 和 125 都在,也会报 ORA-00308: cannot open archived log。
正确做法是切换粒度:
- 查出备库当前应用到的 SCN:
SELECT CURRENT_SCN FROM V$DATABASE;(假设返回2791087) - 查主库归档覆盖的 SCN 区间:
SELECT FIRST_CHANGE#, NEXT_CHANGE#, SEQUENCE# FROM V$ARCHIVED_LOG WHERE SEQUENCE# IN (124,125); - 选一个明确落在已有归档区间内的 SCN,例如
2791500,然后在备库 mount 状态下运行:RECOVER DATABASE UNTIL SCN 2791500; - 注意:该操作需先
SHUTDOWN IMMEDIATE备库,再STARTUP MOUNT,最后执行 recover
真正容易被忽略的是:SCN 必须严格落在某个已注册归档的 FIRST_CHANGE# 和 NEXT_CHANGE# 之间;跨区间会导致 recover 停在上一个可用归档末尾,而不是你指定的 SCN。











