根本原因是rman未同步控制文件与rman资料库元数据,导致v$archived_log中残留deleted='no'且status='available'的“幽灵归档”记录,使fra空间统计不释放。
根本原因不是rman没删文件,而是它没同步控制文件和rman资料库的元数据记录——oracle仍“认为”那些归档日志还存在,所以fra空间统计不降,df -h自然看不到释放。
为什么DELETE ARCHIVELOG后df -h不减?
执行DELETE ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-7'这类命令,RMAN只做两件事:删物理文件、更新自身资料库(如果用了catalog)。但它不会自动清理控制文件中残留的状态为AVAILABLE或EXPIRED的记录。而v$recovery_file_dest的空间计算,完全依赖控制文件里的v$archived_log视图——哪怕文件早被rm光了,只要那条记录的deleted='NO'且status='AVAILABLE',它就继续算进已用空间。
- 典型现象:
ls -l /u01/fast_recovery_area/.../ARCHIVELOG为空,但SELECT ROUND(space_used/space_limit*100, 2) FROM v$recovery_file_dest仍显示98% - 验证是否存在“幽灵归档”:
SELECT name, status, deleted FROM v$archived_log WHERE status = 'AVAILABLE' AND deleted = 'NO' AND completion_time - 关键点:
DELETE命令本身不触发CROSSCHECK,所以控制文件对文件真实状态“失联”
CROSSCHECK必须在DELETE前手动执行
RMAN的CROSSCHECK不是可选步骤,它是重建元数据一致性的强制握手过程。它扫描指定路径(如FRA或log_archive_dest_1),比对控制文件记录与OS实际文件存在性,并把缺失的条目标记为EXPIRED。
- 必须顺序执行:
CROSSCHECK ARCHIVELOG ALL→DELETE NOPROMPT EXPIRED ARCHIVELOG ALL - 跳过
CROSSCHECK直接DELETE EXPIRED:报错no archived log of thread 1 with sequence # found - 只对FRA外的自定义归档路径有效:
CROSSCHECK ARCHIVELOG OF DESTINATION 1(对应log_archive_dest_1) - 注意:
CROSSCHECK本身不删任何东西,也不释放空间,只是“摸清底数”
归档未APPLIED或策略锁死也会拦住空间释放
即使元数据干净,RMAN仍可能拒绝删除——因为Data Guard应用状态或保留策略在后台“锁住”了归档生命周期。
- 备库上归档未
APPLIED:SELECT * FROM v$archived_log WHERE applied = 'NO',此时DELETE ARCHIVELOG UNTIL TIME会被策略拦截 - 检查当前策略:
SHOW ARCHIVELOG DELETION POLICY,常见陷阱是TO BACKED UP 2 TIMES TO DEVICE TYPE DISK——备份只完成1次,归档就被冻结 - 紧急绕过(慎用):
CONFIGURE ARCHIVELOG DELETION POLICY TO NONE,操作完立刻恢复原策略 -
DELETE FORCE ARCHIVELOG能跳过所有检查,但会破坏DG一致性,仅限崩溃后手动救急
还有进程在写被删的归档文件?lsof得看一眼
极少数情况下,归档进程(如ARCH)、RMAN通道或第三方备份工具仍持有已rm文件的句柄,导致操作系统无法回收块。这不是Oracle逻辑问题,而是Linux文件系统特性。
- 快速检测:
lsof +L1 | grep deleted,输出里带deleted字样的行就是罪魁 - 定位进程:
lsof /path/to/archivelog/dir | grep deleted - 常规处理:重启对应进程(如
kill -9 <pid></pid>),不要重启DB实例或整个OS - 预防:归档目录避免被其他脚本
tail -f或日志轮转工具长期打开
最常被忽略的是:CROSSCHECK后必须跟DELETE EXPIRED,而不是只信DELETE ARCHIVELOG ...的返回信息;另外,v$recovery_file_dest的Pct Used才是FRA真实水位,df -h只是干扰项。











