PURGE RECYCLEBIN仅清当前用户回收站,不释放全库空间;需SYSDBA权限执行PURGE DBA_RECYCLEBIN才能清空所有回收站对象,且操作不可逆、不触发触发器。
purge recyclebin 不清空全库回收站,只清当前用户
很多人执行 PURGE RECYCLEBIN 后发现表空间没释放,第一反应是“命令失效”,其实只是清理范围太小。这个命令只作用于当前登录用户的 USER_RECYCLEBIN,哪怕你用 sys 登录但没切容器(ALTER SESSION SET CONTAINER = pdb_name),在 CDB$ROOT 下执行也只清 sys 用户自己的回收站条目,不会动其他 PDB 或其他用户的对象。
常见误判场景:
- 用普通开发账号连库,执行
PURGE RECYCLEBIN→ 只清自己 DROP 过的表,DBA 用户或应用账号的回收站还在占空间 - 多租户环境下,用
sys连 CDB$ROOT 执行 → 仍只清 CDB$ROOT 容器内sys的回收站,各 PDB 里的回收站完全不受影响 - 查
DBA_RECYCLEBIN发现还有几百条记录 → 说明PURGE RECYCLEBIN根本没覆盖到那些对象,得换权限或换容器
确认是否生效:执行后立刻查 SELECT COUNT(*) FROM USER_RECYCLEBIN;,应为 0;再查 DBA_SEGMENTS WHERE SEGMENT_NAME LIKE 'BIN$%' 看对应段是否消失。
PURGE DBA_RECYCLEBIN 需 SYSDBA 权限且不可逆
想真正释放全库回收站空间,必须用有 SYSDBA 权限的账户(如 sys / as sysdba)执行 PURGE DBA_RECYCLEBIN。这不是“带 DBA 角色就行”,而是硬性权限要求——普通 DBA 角色用户执行会直接报 ORA-01031: insufficient privileges。
关键事实:
- 执行后所有回收站对象的段(segment)被立即标记为可重用,
DBA_SEGMENTS中对应记录消失 - 空间不会返还给操作系统(
df -h不变),但会进入表空间空闲列表,下次建表/插入自动复用 - 无法恢复:任何被清掉的对象都不能再用
FLASHBACK TABLE ... TO BEFORE DROP - 不支持
WHERE过滤:不能写PURGE DBA_RECYCLEBIN WHERE OWNER = 'SCOTT',想按用户清,得用PURGE USER scott
回收站对象仍占空间,但名字已不是原名
回收站里的表、索引等,物理段仍在原表空间里,只是段名被 Oracle 改成 BIN$xxx$0 这类格式。所以 DBA_SEGMENTS 查不到 ORIGINAL_NAME,不代表空间已释放——反而正是它还在占空间的证据。
查真实占用量:
- 看哪些表空间被回收站拖累:
SELECT tablespace_name, SUM(bytes)/1024/1024 AS mb FROM dba_segments WHERE segment_name LIKE 'BIN$%' GROUP BY tablespace_name; - 确认回收站是否启用:
SHOW PARAMETER recyclebin,输出值必须是ON(10g+ 默认开启) - 别信
DBA_FREE_SPACE立刻上涨:ASSM 表空间下空间释放后先更新本地位图,查DBA_TABLESPACE_USAGE_METRICS更准
清完 PURGE DBA_RECYCLEBIN,df -h 没变化是正常现象
执行成功后 df -h 显示数据文件大小不变,不等于没清干净。Oracle 只是把那些 Extent 标记为“可分配”,并不主动 shrink 数据文件。真正腾出 OS 层磁盘空间,要靠后续操作:
- 手动缩小文件:
ALTER DATABASE DATAFILE '/path/to/users01.dbf' RESIZE 500M;,但前提是文件末尾没活动段(得先 MOVE 表/索引腾尾部) - 合并碎片:
ALTER TABLESPACE users COALESCE;,只整理 LMT 表空间内相邻空闲 Extent,不减少文件大小 - 日常优先级:先确保回收站已清空,再考虑 COALESCE 或 RESIZE;后者风险高、耗时长,多数情况下没必要
最常被忽略的一点:PURGE 操作本身不触发任何触发器、约束检查或日志归档,但它释放的是段头块和 Extent 元数据——这部分一旦丢失,连底层块扫描都救不回来。所以执行前,务必确认没有尚未知会的恢复需求,尤其在生产变更窗口期。











