回收站对象仍驻留在原表空间中,drop table仅重命名段为bin$格式并逻辑标记,不释放空间;需purge显式清理,且os层空间释放还依赖进程句柄释放或重启数据库。

回收站对象仍驻留在原表空间中
Oracle 19c 的 recyclebin 默认开启,执行 DROP TABLE 并不会物理删除段(segment),而是将对象重命名(如 BIN$abc123$0)并保留在**原表空间**内。这意味着:表空间的 dba_segments 总字节数不变,dba_free_space 不增加,OS 层磁盘空间自然不释放。
常见误判是查不到原表名就认为空间已释放——错。必须用以下语句确认真实占用:
SELECT tablespace_name, SUM(bytes)/1024/1024/1024 AS gb FROM dba_segments WHERE segment_name LIKE 'BIN$%' GROUP BY tablespace_name;
PURGE DBA_RECYCLEBIN 执行后空间仍不更新
即使成功执行 PURGE DBA_RECYCLEBIN,df -h 也可能看不到磁盘空间增加。这不是命令失败,而是 Oracle 进程(如 DBW0、CKPT)仍持有已 unlink 的数据文件句柄,Linux 内核无法立即回收块。
验证方式:
- 运行
lsof | grep deleted,若看到类似/u01/oradata/ORCL/users01.dbf (deleted)的输出,说明句柄未释放 - 用
kill -9 <pid></pid>终止对应后台进程(通常为 DBWn),等待 10–30 秒后df -h一般会更新 - 若不敢 kill 进程,可执行
SHUTDOWN IMMEDIATE+STARTUP强制关闭所有句柄
多租户环境下 PURGE 失效的常见原因
在 CDB/PDB 架构中,PURGE DBA_RECYCLEBIN 在 CDB$ROOT 下执行,只清理根容器中的回收站对象,不会自动遍历各 PDB。如果你的表在 HR_PDB 中被 DROP,必须先 ALTER SESSION SET CONTAINER = HR_PDB,再执行 PURGE RECYCLEBIN 或 PURGE DBA_RECYCLEBIN(需该 PDB 内 SYSDBA 权限)。
另外注意:
-
PURGE DBA_RECYCLEBIN必须由真正具备SYSDBA权限的用户(如SYS)执行,仅授予DBA角色的普通用户无法成功 - 若回收站中某对象正被其他会话查询(如
SELECT * FROM "BIN$xxx"),会报ORA-38301,该对象会被跳过,不触发清理 - 执行后务必查
DBA_RECYCLEBIN确认是否为空,不能只看有无报错
如何避免回收站干扰空间管理
对运维或批量清理场景,最稳妥的做法是绕过回收站机制本身:
- 删单表时直接加
PURGE后缀:DROP TABLE t1 PURGE,一步到位,不进回收站 - 临时禁用当前会话回收站:
ALTER SESSION SET recyclebin = OFF,后续所有DROP都立即释放空间 - 全局禁用(慎用):
ALTER SYSTEM SET recyclebin = OFF,但会丧失误删恢复能力,且部分版本要求重启生效 - 定期清理策略建议用
PURGE TABLESPACE users USER scott这类限定范围的命令,比全库清空更安全、低风险
真正释放空间的关键不在“删”,而在“段是否从数据文件中移除”——而回收站让这个移除动作变成了显式、可选、有时还受进程句柄阻塞的操作。别只盯着 DROP,得盯住 PURGE 和 lsof。











