Oracle 11g默认开启回收站,DROP TABLE仅重命名入回收站而非物理删除,空间不释放;需用DROP TABLE ... PURGE或PURGE TABLE "BIN$..."立即释放段空间,但数据文件需手动RESIZE或SHRINK才能释放OS层磁盘空间。
DROP TABLE 后空间没释放?先确认是不是卡在回收站
oracle 11g 默认开启 recyclebin,drop table 不是物理删除,而是重命名后塞进回收站(如 bin$abc123==$0),段仍占数据文件空间。所以 df -h 看不到磁盘变大,dba_segments 里还能查到该表段,all_tables 甚至可能显示残留记录——这不是 bug,是机制使然。
验证方式很简单:
- 查当前用户回收站:
SELECT object_name, original_name, type, droptime FROM user_recyclebin; - 查段占用:
SELECT segment_name, bytes/1024/1024 MB FROM dba_segments WHERE segment_name LIKE 'BIN%'; - 确认回收站开关:
SHOW PARAMETER recyclebin;(值为ON才会触发此行为)
单表立即释放空间:用 PURGE 而不是 DROP
如果确定不要恢复这张表,别等自动清理,也别事后 purge,直接一步到位:
-
DROP TABLE t1 PURGE;—— 最干净,不进回收站,段立刻释放,dba_segments和 OS 层空间同步更新 - 注意:
PURGE不走触发器、不检查约束、不可逆,执行前务必 double-check 表名 - 若已执行过普通
DROP,现在想补救:PURGE TABLE "BIN$abc123==$0";(引号不能省,名字含特殊字符)
批量清空回收站:按用户或全局清理
开发/测试库常因反复建表删表堆积大量 BIN$ 对象,手动逐个 purge 效率低,推荐批量操作:
- 清空当前用户回收站:
PURGE RECYCLEBIN; - 清空所有用户回收站(需 DBA 权限):
PURGE DBA_RECYCLEBIN; - 生成 purge 脚本(避免漏表):
SELECT 'PURGE TABLE "'||owner||'"."'||object_name||'";' FROM dba_recyclebin WHERE type = 'TABLE';
注意:PURGE RECYCLEBIN 只影响当前会话用户,不会动其他 schema;而 PURGE DBA_RECYCLEBIN 是全局动作,生产环境慎用。
空间释放了但数据文件没缩?那是另一个问题
PURGE 成功后,dba_data_files.bytes 不变是正常的——Oracle 不自动收缩数据文件,只是把段空间标记为“可重用”。真正释放 OS 层磁盘空间,需要额外操作:
- 若表空间是
AUTOEXTEND OFF,且你确认后续无增长需求,可用ALTER DATABASE DATAFILE '/path/to/file.dbf' RESIZE N M;手动缩小 - 若启用了
AUTOEXTEND,文件不会自动回缩,得先RESIZE再关AUTOEXTEND - 更稳妥的方式是用
ALTER TABLESPACE ... SHRINK SPACE;(要求段启用ROW MOVEMENT,且非字典管理表空间)
别指望 PURGE 自动搞定文件系统层的事,那是两个层级的释放:段级(PURGE)和文件级(RESIZE 或 SHRINK),容易漏掉后者。











