DBA_FREE_SPACE不能单独查使用率,因它只存空闲块总和而无表空间总容量,须与DBA_DATA_FILES左连接并用NVL处理空值,同时排除临时表空间、考虑AUTOEXTENSIBLE及回收站影响。
dba_free_space 单独查不出使用率——它只存空闲块,没总大小。必须和 dba_data_files 连表算,否则结果全是错的。
为什么 DBA_FREE_SPACE 不能直接查使用率
这张视图只记录当前可分配的空闲 extent(区),字段 BYTES 是空闲空间总和,但没有对应表空间的“总容量”。你看到 USERS 表空间有 1.2 GB 空闲,却不知道它总共才 2 GB 还是 200 GB。单独查它,等于只看零钱盒里剩多少钱,不看工资卡总额。
-
DBA_FREE_SPACE不包含临时表空间、UNDO 表空间的空闲信息(它们走另一套管理逻辑) - 某些小表空间可能长期没空闲块,
DBA_FREE_SPACE里压根没记录该表空间的行 - 高水位线(HWM)以下未格式化的块,不会出现在
DBA_FREE_SPACE中,但也不能被新数据直接用
DBA_DATA_FILES 和 DBA_FREE_SPACE 必须 LEFT JOIN
主表必须是 DBA_DATA_FILES,因为每个数据文件都代表真实物理容量;DBA_FREE_SPACE 是“附属状态”,可能为空。如果用 INNER JOIN 或逗号连接,那些刚建好还没写入数据、或已满到没空闲块的表空间会直接从结果里消失。
- 连表条件必须显式写
ON t1.TABLESPACE_NAME = t2.TABLESPACE_NAME,不能靠隐式关联 -
SUM(t2.BYTES)前必须套NVL(SUM(t2.BYTES), 0),否则空组返回NULL,导致整行USED_PCT变成NULL - 过滤临时表空间要加:
WHERE t1.TABLESPACE_NAME NOT IN (SELECT TABLESPACE_NAME FROM DBA_TABLESPACES WHERE CONTENTS = 'TEMPORARY')
自动扩展(AUTOEXTENSIBLE)会让结果失真
如果文件设了 AUTOEXTENSIBLE = 'YES',DBA_DATA_FILES.BYTES 是当前大小,不是上限。监控时若只看当前使用率,可能误判“快满了”,其实磁盘还有空间、Oracle 还能自动扩。
- 真实可用空间应参考
MAXBYTES,而不是BYTES - 但注意:
MAXBYTES = 0表示不限制,MAXBYTES = BYTES表示不可扩展 - 紧急排查爆满问题时,优先查
BYTES = MAXBYTES且USED_PCT > 95的文件,这才是真瓶颈
回收站(RECYCLEBIN)会吃掉“看不见”的空间
删掉的大表不会立刻释放空间,而是进回收站,仍占用 DBA_FREE_SPACE 统计不到的已分配空间。执行 DROP TABLE ... PURGE 或清空回收站后,USED_PCT 才会下降。
- 检查回收站对象:运行
SELECT * FROM RECYCLEBIN; - 清空当前用户回收站:
PURGE RECYCLEBIN; - 清空全库回收站(需 DBA 权限):
PURGE DBA_RECYCLEBIN; - 这个操作不可逆,执行前确认无误
最常被忽略的是 RAC 环境下 DBA_FREE_SPACE 的本地性——它只反映当前节点缓存的空闲块,跨节点必须逐个登录查,不能取一个节点的结果代表整个集群。


















