DELETE EXPIRED BACKUP 不删文件只清控制文件中已标为 EXPIRED 的元数据;手动删除备份文件后未执行 CROSSCHECK BACKUP ALL,记录仍为 AVAILABLE/UNAVAILABLE,故无对象可删。

DELETE EXPIRED BACKUP 为什么一条没删?
它本来就不删文件,只清控制文件里已标为 EXPIRED 的元数据记录。你手动 rm 了备份文件,但没进 RMAN 执行 CROSSCHECK BACKUP,控制文件里那条记录还是 AVAILABLE 或 UNAVAILABLE,根本不会变成 EXPIRED —— 所以 DELETE EXPIRED BACKUP 查不到可删项,返回 0 objects deleted 是正常现象。
常见漏点:
-
CROSSCHECK BACKUP默认只查最近一次备份集,必须加ALL:用CROSSCHECK BACKUPSET ALL、CROSSCHECK COPY ALL - 路径权限不足、NFS 挂载异常时,
CROSSCHECK会跳过部分文件,导致没打上EXPIRED - 用了恢复目录(recovery catalog)但没运行
RESYNC CATALOG,主库控制文件和目录状态不一致,EXPIRED判定失效
归档日志删不干净,FRA 空间还不释放?
归档日志元数据比备份更顽固。哪怕你执行了 DELETE ARCHIVELOG ALL,v$archived_log 和控制文件里仍可能残留 DELETED 或 EXPIRED 状态,FRA 使用率也不下降。关键在闭环三步:
- 先
CROSSCHECK ARCHIVELOG ALL:强制扫描磁盘,把物理缺失的归档标为EXPIRED - 再
DELETE NOPROMPT EXPIRED ARCHIVELOG ALL:清掉这些“僵尸记录”,这是释放 FRA 配额的前提 - 最后
DELETE NOPROMPT ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-7':按业务窗口删有效归档(注意:COMPLETED BEFORE查的是v$archived_log.completion_time,不是文件修改时间)
如果归档路径不在 FRA(比如用了 log_archive_dest_1),要额外检查该路径下文件是否真实存在、是否有写权限。
Data Guard 环境下清理备库归档要特别小心
备库上不能直接删归档文件,也不能随便跑 CROSSCHECK。必须先确认归档已完全应用且无 GAP:
- 查
v$archived_log中APPLIED = 'YES'的归档才真正安全(STATUS = 'A'只是辅助) - 执行
SELECT thread#, low_sequence#, high_sequence# FROM v$archive_gap;,返回空才算无 GAP - 备库上
CROSSCHECK ARCHIVELOG ALL必须加限定:CROSSCHECK ARCHIVELOG ALL FOR DB_UNIQUE_NAME <primary_name></primary_name>,否则默认查本地角色,可能误标或漏标 - 删的时候用
DELETE NOPROMPT ARCHIVELOG UNTIL TIME 'SYSDATE - 3',并显式指定FROM DEST_ID 1避免跨目标误删
删完还剩 STATUS = DELETED 的备份记录?
这是正常行为。DELETE EXPIRED BACKUP 只删备份集(BACKUPSET)和映像副本(COPY)主记录,不自动级联清理碎片,比如 RC_BACKUP_PIECE 表里的孤立备份片条目、或未解绑的归档日志关联关系。
不要直接操作控制文件。安全做法是:
- 先用
LIST EXPIRED BACKUP确认是否真有残留;若有,说明CROSSCHECK没扫全路径,或某些备份片因权限问题被跳过 - 对已确认物理文件彻底丢失、且
CROSSCHECK失败的个别条目,可用CHANGE BACKUPSET <bs_key> UNCATALOG</bs_key>显式注销 - 极端情况(如控制文件损坏或大量元数据错乱)才考虑重建控制文件
最易被忽略的点:control_file_record_keep_time 默认约 7 天,超期归档在控制文件中无记录,RMAN “看不见”,这部分必须手工清理,且清理前要确认它们不在任何备份集中、也不参与恢复流程。


















