keep forever 不能防误删,因其仅跳过 delete obsolete 检查,不阻止手动删除、fra 自动清理、控制文件记录覆盖或元数据未注册导致的“不可见”;真正防护需路径隔离、显式 catalog、延长 control_file_record_keep_time 及存储层 worm 锁定。

单纯给备份加 KEEP FOREVER 不防误删,真正起作用的是存储层控制 + 元数据绑定 + 人工干预点设计。
为什么 DELETE OBSOLETE 还是能删掉 KEEP FOREVER 备份
根本原因不是 RMAN 忘了标记,而是它压根没把那些文件当“备份”看。常见触发场景:
-
KEEP FOREVER只作用于已注册进 RMAN 库的BACKUPSET或COPY;如果备份后没执行CATALOG START WITH '/path/',RMAN 就不知道磁盘上那些文件是它的 - FRA(
db_recovery_file_dest)下的KEEP FOREVER文件仍会被 FRA 自动清理机制删除——Oracle 明确文档行为,不是 bug - 手动执行
DELETE BACKUPSET 123或DELETE FORCE BACKUP会绕过所有保留策略,直接物理删除
必须做的三道硬隔离防线
缺一不可,否则任何“防误删”都是纸面功夫:
-
路径隔离:所有
KEEP FOREVER备份必须写入独立目录(如/backup/annual/),且该路径不能是 FRA、不能挂载在 NFS 但无写保护、不能由其他进程共享写入 -
元数据绑定:备份完成后立即执行
CATALOG START WITH '/backup/annual/',确保 RMAN 控制文件里存有每一份文件的校验和与时间戳 -
控制文件记录周期匹配:运行
ALTER SYSTEM SET CONTROL_FILE_RECORD_KEEP_TIME = 1095 SCOPE=BOTH(对应 3 年),否则超过该天数的KEEP FOREVER记录会在控制文件中被覆盖,RESTORE时找不到元数据
MinIO/S3 存储侧的防误删加固(推荐生产用)
如果备份目标是 MinIO 或兼容 S3 的对象存储,仅靠 RMAN 层不够,必须启用底层防护:
- 建桶时启用版本控制:
mc version enable minio-test/oracle-backup,误删后可回溯旧版本 - 建桶时启用对象锁定(需桶新建时指定):
mc mb --with-lock minio-test/oracle-backup,之后所有对象默认受 WORM(一次写入多次读取)保护 - 禁止使用
mc rm直接删对象,所有清理必须走生命周期策略(mc ilm add)或带合规保留期的脚本
最容易被忽略的两个执行细节
哪怕路径、策略、存储都配对了,这两步漏掉,备份照样白做:
- 每次
BACKUP DATABASE命令必须显式带FORMAT,例如BACKUP DATABASE FORMAT '/backup/annual/db_%U.bak';RMAN 不继承CONFIGURE CHANNEL设置,也不认环境变量 -
CONTROLFILE AUTOBACKUP必须单独配置路径:CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '/backup/annual/cf_%F.ctl',%F是强制占位符,不能用%U
防误删的本质不是加一个关键字,而是让备份文件同时满足:路径可控、元数据在线、存储层锁死、操作入口收窄。任何环节松动,就等于在保险柜上留了把明锁。











