回收站对象确实占用空间,需先查dba_segments中bin$段确认;purge后空间可复用但不缩文件,cdb下默认跨容器清理,按pdb/用户/表清理需指定方式,附属段清除但外键约束残留需手动处理。

确认回收站是否真在占空间
别急着 PURGE,先看空间是不是真被回收站对象锁住了。执行 SELECT SUM(bytes)/1024/1024 FROM dba_free_space WHERE tablespace_name = 'USERS'; 拿到空闲空间值;再查 SELECT SUM(bytes)/1024/1024 FROM dba_segments WHERE segment_name LIKE 'BIN$%'; —— 如果后者有非零结果,说明 BIN$ 段确实还在占空间,且没被 purge 掉。
常见误判:df -h 看磁盘没变小,就以为 PURGE 失败。其实 Oracle 只是把 Extent 标记为可重用,不 shrink 数据文件,操作系统层面的磁盘使用率不会下降。
PURGE DBA_RECYCLEBIN 不等于“一键清空全库”
PURGE DBA_RECYCLEBIN 在 CDB 环境下默认作用于当前容器(CDB$ROOT 或某个 PDB),但很多人连 CDB$ROOT 执行后才发现所有 PDB 的回收站也被清了——因为 DBA_RECYCLEBIN 视图默认跨容器聚合数据。
- 想只清某个 PDB?先
ALTER SESSION SET CONTAINER = pdb_name;,再执行PURGE DBA_RECYCLEBIN - 想按用户清理?用
PURGE USER scott;(需 DBA 权限),比遍历DBA_RECYCLEBIN安全高效 - 想清单个表?查出它的
OBJECT_NAME(比如BIN$abc123$0),然后PURGE TABLE "BIN$abc123$0";—— 注意双引号,名字含特殊字符 - 普通用户不能执行
PURGE DBA_RECYCLEBIN,报ORA-01031: insufficient privileges就停手,别硬试
PURGE 后段空间没立刻“返还”,但已可复用
执行成功后,对应段在 DBA_SEGMENTS 中消失,说明 Oracle 已将其 Extent 归入表空间空闲列表。下次建表、插入或扩展索引时,会自动分配这些块。
但以下情况会导致空间“看似没释放”:
- 表空间设了
AUTOEXTEND ON,新数据优先写入新增文件,旧空闲块可能长期闲置 - 存在大分区表,其 LOB 段若独立存储,
PURGE DBA_RECYCLEBIN不会动它(除非该 LOB 属于被删表) - 对象被物化视图日志或启用
ROW MOVEMENT依赖,PURGE 表本身不清理关联日志,得单独DROP MATERIALIZED VIEW LOG
验证是否生效:再跑一遍 SELECT SUM(bytes)/1024/1024 FROM dba_segments WHERE segment_name LIKE 'BIN$%';,应返回 0 或空。
绕过回收站的 drop 更快,但不可逆
如果确定不要恢复,建表前就加 PURGE:例如 DROP TABLE t1 PURGE;。这跳过回收站,直接释放段,避免后续清理成本。
但要注意:
-
DROP TABLESPACE、DROP USER、DROP CLUSTER这类 DDL 会自动清空关联回收站对象,无需额外 PURGE -
SYS和SYSTEM表空间下的对象不进回收站,FLASHBACK TABLE对它们无效 - 禁用回收站(
ALTER SYSTEM SET recyclebin = OFF;)对已有 BIN$ 对象无影响,只影响后续 DROP
最易被忽略的一点:PURGE 掉的对象,连同它的索引、约束、触发器等附属段一并清除,但不会清理外键引用它的其他表上的约束——那些残留的 INVALID 约束得手动处理。











