RMAN不自动删除归档日志的根本原因是“可删除”状态未触发,依赖控制文件中归档日志元数据完整且标记为“已备份且无依赖”,而生产环境中常因记录老化、备份反馈丢失、备库未应用或策略未配置导致失效。
rman 不自动删除归档日志,根本不是命令写得不对,而是“可删除”状态没被正确触发——它依赖控制文件中归档日志的元数据是否完整、是否标记为“已备份且无依赖”,而这两点在多数生产环境里都容易断链。
为什么 BACKUP ARCHIVELOG ALL DELETE INPUT 有时不生效
这条命令本身没问题,但执行前提很苛刻:RMAN 必须在控制文件里查到每一条待删归档的日志记录,并确认它已被成功备份、且不被 Data Guard / Streams 等进程依赖。常见断点包括:
- 控制文件中归档日志记录已老化被覆盖(
control_file_record_keep_time默认 7 天,超期后 RMAN 就“看不见”那些日志) - 归档日志实际已备份,但 RMAN 没收到成功反馈(比如 NBU 调用 RMAN 脚本时,
DELETE INPUT语句被跳过或未执行完) - 数据库配置了
ARCHIVELOG DELETION POLICY TO APPLIED ON STANDBY,但备库还没应用完,RMAN 就卡住不删 - RUN 块中前面的备份命令失败(如磁盘满、权限错),导致后续
DELETE INPUT根本不执行
如何强制让归档备份后立即清理
别只靠 DELETE INPUT,要加一层兜底逻辑和显式校验:
- 改用
BACKUP ARCHIVELOG ALL DELETE ALL INPUT—— 它比DELETE INPUT更激进,不检查是否“仅备份一次”,直接删所有已备份的归档(适合单实例或确认备库同步及时的场景) - 在 backup 后立刻跟
CROSSCHECK ARCHIVELOG ALL+DELETE NOPROMPT EXPIRED ARCHIVELOG ALL,把控制文件里“失效但残留”的记录清掉 - 如果归档写在本地磁盘(尤其 RAC 各节点独立路径),必须为每个实例分配独立 channel,否则 crosscheck 会误判其它节点日志“不存在”而批量标 expired
- 避免把
DELETE和BACKUP写在同一个 RUN 块里;拆成两个独立 RUN 块,防止前序失败导致清理丢失
归档删除策略被忽略的隐藏开关
很多人漏掉一个关键配置:CONFIGURE ARCHIVELOG DELETION POLICY。它不设默认值,意味着 RMAN 默认“不敢删”,哪怕你写了 DELETE INPUT,只要策略没配,它仍可能因保护机制拒删:
-
CONFIGURE ARCHIVELOG DELETION POLICY TO BACKED UP 1 TIMES TO DISK:只要备份过一次就允许删(最常用) -
CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON STANDBY:必须等备库v$archived_log.applied = 'YES'才能删,查SELECT * FROM v$archive_dest_status WHERE status = 'VALID'确认备库状态 - 一旦设了策略,记得用
SHOW ARCHIVELOG DELETION POLICY验证是否生效,RMAN 不报错也不等于已加载
删完归档,磁盘空间却不释放?
这不是 RMAN 的问题,是操作系统层面的文件句柄未释放:
- 执行
lsof | grep arch查看是否有进程(如正在运行的 RMAN session、NBU agent、甚至旧的 sqlplus 连接)还 hold 着已删归档的 fd - 特别注意 RAC 环境下,归档日志若存于 ASM,
DELETE INPUT只删 ASM alias,物理块可能延迟回收;需配合ALTER DISKGROUP ... REBALANCE POWER 5加速 - 如果用脚本定期清理,务必在
DELETE后加crosscheck archivelog all,否则下次 backup 时 RMAN 仍可能尝试读取已删路径,报ORA-19505: failed to identify file
真正麻烦的从来不是“怎么写命令”,而是控制文件元数据、备库应用状态、OS 文件句柄这三者之间的时间差——它们不同步时,RMAN 就会沉默地跳过该删的归档,直到某天 ORA-00257 报出来才意识到空间早满了。











