RMAN的RETENTION POLICY是持久化于控制文件的全局策略,仅能通过CONFIGURE命令配置RECOVERY WINDOW或REDUNDANCY二者之一,决定DELETE OBSOLETE行为;其生效依赖控制文件策略、备份元数据完整性及CONTROL_FILE_RECORD_KEEP_TIME参数协同。
RETENTION POLICY 是 RMAN 的全局策略,不是备份时临时指定的
rman 的 retention policy 是在目标数据库控制文件中持久化存储的配置项,一旦设置,所有后续 backup 命令都会受其约束。它不随某次备份命令传参生效,也不能在 backup 里用 keep 之类覆盖策略逻辑——keep 是绕过策略的例外标记,不是策略本身。
常见错误是以为执行一次 BACKUP DATABASE RETENTION POLICY TO REDUNDANCY 2 就能生效,其实语法根本不存在;正确做法只有两种:CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 7 DAYS 或 CONFIGURE RETENTION POLICY TO REDUNDANCY 3。
-
RECOVERY WINDOW按时间倒推:系统会保留“足以恢复到任意过去 7 天内任一时间点”的最小备份集,不是简单保留最近 7 天的备份 -
REDUNDANCY按份数计:比如设为 2,意味着每个数据文件至少有 2 份可用来恢复的完整备份(含归档日志链),旧备份可能被CROSSCHECK+DELETE OBSOLETE清掉 - 策略只影响
DELETE OBSOLETE行为,不影响DELETE EXPIRED或手动DELETE BACKUP
RECOVERY WINDOW 和 REDUNDANCY 别混用,只能选一个
Oracle 不允许同时启用两种策略。执行第二个 CONFIGURE RETENTION POLICY 命令时,前一个自动失效。很多人在测试环境切来切去,结果忘了查当前生效的是哪个:
SHOW RETENTION POLICY;
输出类似 CONFIGURATION FOR RETENTION POLICY IS: REDUNDANCY 2 或 RECOVERY WINDOW OF 7 DAYS —— 这才是真实生效的依据。
- 用
RECOVERY WINDOW更适合业务有明确 RPO 要求的场景(如“必须能恢复到 2 小时前”) - 用
REDUNDANCY更适合空间受限、但对时间点无硬性要求的环境(比如开发库只要两份备份防误删) - 如果归档日志没开或被手动删过,
RECOVERY WINDOW可能无法达成目标,RMAN 会静默降级(不报错,但LIST OBSOLETE显示的备份比预期少)
DELETE OBSOLETE 不等于自动清理,得先 CROSSCHECK
DELETE OBSOLETE 判断“过期”的依据,是控制文件里记录的备份元数据 + 当前 RETENTION POLICY。但如果磁盘上备份片已被人工删掉、或 NFS 挂载异常导致路径不可达,控制文件还记着它,这时 DELETE OBSOLETE 不会动它,也不会报错 —— 它只删“策略判定过期且物理存在”的备份。
所以生产环境务必加一步:
CROSSCHECK BACKUP;<br>DELETE EXPIRED BACKUP;<br>DELETE OBSOLETE;
-
CROSSCHECK扫描控制文件里每条备份记录,确认对应.bkp文件是否还在磁盘上 -
DELETE EXPIRED清理那些记录还在但文件已丢的“幽灵条目” - 再跑
DELETE OBSOLETE,才能准确释放空间 - 漏掉
CROSSCHECK,可能造成磁盘爆满却始终不清理,或者REPORT OBSOLETE显示有 10 份可删,实际DELETE OBSOLETE一行都不执行
ARCHIVELOG 的保留受 CONTROL_FILE_RECORD_KEEP_TIME 影响
RMAN 对归档日志的过期判断,不仅看 RETENTION POLICY,还受参数 CONTROL_FILE_RECORD_KEEP_TIME(默认 7 天)限制。如果归档日志的记录在控制文件中已被覆盖,即使它物理还在磁盘上,DELETE OBSOLETE 也看不到它,更不会删。
- 该参数控制控制文件中归档日志历史记录的保留天数,不是备份策略的一部分,但和策略效果强耦合
- 若设得太小(比如 1),而你的
RECOVERY WINDOW是 7 天,RMAN 根本查不到 2 天前的归档记录,自然无法判断哪些归档该留、哪些该删 - 调整需重启实例生效,建议设为 ≥
RECOVERY WINDOW值,且不低于 14 天(留出维护窗口) - 查询当前值:
SHOW PARAMETER CONTROL_FILE_RECORD_KEEP_TIME
DELETE OBSOLETE 就可能变成“看起来在运行,其实什么都没删”。










