物理备库不会自动删除数据文件,drop tablespace including contents and datafiles 在备库仅更新数据字典,操作系统文件仍保留;需先取消恢复、确认无待应用日志、手动删除文件、再重启恢复,并检查句柄及undo/temp残留。
主库执行 drop tablespace ... including contents and datafiles 后,备库磁盘空间没变
这不是备库“没同步”,而是 oracle data guard 的物理备库(physical standby)根本不会自动删除数据文件。主库的 drop tablespace 语句在备库上重放时,只删数据字典记录(dba_tablespaces 等视图更新),但操作系统层面的 .dbf 文件仍躺在备库磁盘上——因为物理备库的恢复机制不处理文件系统级操作。
为什么 INCLUDING CONTENTS AND DATAFILES 在备库无效
该子句仅对主库本地文件系统生效;DG 的 Redo Apply 过程不解析或执行文件系统命令。即使主库成功删掉 /u01/oradata/PROD/ts01.dbf,备库的同名文件依然存在,且被 MRP(Managed Recovery Process)进程持续打开(lsof | grep deleted 可能显示其为 “deleted” 状态但未释放空间)。
- 备库的
v$recover_file或dba_data_files里仍能看到该数据文件,状态为OFFLINE或RECOVER -
SELECT file_name, status FROM v$datafile WHERE tablespace_name = 'TS_NAME';可能返回RECOVER或MISSING - 直接
rm备库文件会触发 MRP 报错(如ORA-00376),导致恢复中断
正确清理备库残留数据文件的步骤
必须在主备库都停用相关表空间、并确认无任何依赖后,手动清理备库文件。关键点:先停恢复,再删文件,最后重启恢复。
- 在备库上停止应用日志:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL; - 确认该表空间在备库已无活动恢复需求:
SELECT * FROM v$recovery_log WHERE thread# = 1 AND sequence# > (SELECT MAX(sequence#) FROM v$archived_log WHERE name LIKE '%ts01%');(若无结果,说明无待应用日志涉及该表空间) - 从操作系统删除对应
.dbf文件(路径需与主库一致,或通过SELECT name FROM v$datafile WHERE ts# = (SELECT ts# FROM v$tablespace WHERE name = 'TS_NAME');确认) - 重启恢复:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT; - 验证:
SELECT file_name, status FROM v$datafile WHERE tablespace_name = 'TS_NAME';应返回空集
容易被忽略的两个硬坑
一是备库可能有其他进程(如 RMAN、expdp、甚至旧会话的临时段)隐式持有已删文件句柄,lsof | grep -i "ts01.dbf" 必须清零才能真正释放磁盘空间;二是如果该表空间曾用于 undo 或 temp,需额外检查 v$tempfile 和 v$undostat 是否仍有残留引用——这些对象不随表空间删除自动清理,必须单独处理。











