dba_free_space的bytes总和不小于表空间总空闲量,其差异源于它仅统计连续空闲extent而非碎片化小块;真正影响业务的是能否满足下一次extent分配需求。
查 dba_free_space 时为什么 bytes 加起来远小于表空间总空闲量?
因为 dba_free_space 记录的是“连续空闲 extent”,不是字节池。同一表空间里,哪怕只剩 10mb 空闲,如果被切成 200 个 50kb 的碎片块,dba_free_space 就会返回 200 行——但每行的 bytes 都很小,sum(bytes) 却和总空闲一致。问题不在数据不准,而在你误把“连续块数量”当成了“碎片程度”。
真正要算碎片率,得看这些空闲块的大小分布,尤其关注能否满足下一次分配需求(比如默认 INITIAL 是 64KB 或 1MB)。实操建议:
- 别只
SUM(BYTES),先按BYTES分桶统计:用CASE WHEN BYTES 看小碎片占比 - 加
ORDER BY TABLESPACE_NAME, FILE_ID, BLOCK_ID后肉眼扫几行,能快速判断是否存在大量相邻BLOCK_ID差 1 的记录(说明是刚 deallocate 出来的连续块) - 注意
DBA_FREE_SPACE不包含 TEMP 表空间,也不反映 ASSM 下的 bitmap 管理细节——如果是EXTENT MANAGEMENT LOCAL AUTOALLOCATE,小碎片天然多,属正常现象
用 BLOCK_ID 和 BYTES 推算相邻空闲块的真实连续长度
BLOCK_ID 和 BYTES 联合才能还原物理连续性。Oracle 每个空闲块记录的是起始 BLOCK_ID 和占用块数(BLOCKS),而 BYTES 是换算值,受 DB_BLOCK_SIZE 影响。直接比 BLOCK_ID 更可靠。
例如两行记录:
- BLOCK_ID = 1000, BLOCKS = 8 → 占用 1000~1007
- BLOCK_ID = 1008, BLOCKS = 16 → 紧接着,实际是连续 24 块
实操建议:
- 自连接查询相邻块:用
t1.BLOCK_ID + t1.BLOCKS = t2.BLOCK_ID找可合并的对,并递归或窗口函数扩展成最大连续段 - 别依赖
BYTES做等值匹配,它可能因四舍五入失真;优先用BLOCKS和DB_BLOCK_SIZE(查V$PARAMETER)反推 - 注意文件头和段头保留块(通常前几个
BLOCK_ID不可用),真实连续段要排除BLOCK_ID = 0或极小值的干扰行
碎片率数字本身没意义,关键看是否卡住对象扩容
所谓“碎片率 70%”不意味着系统快崩了,只说明 70% 的空闲空间分布在小块里。真正影响业务的是:下一次建表、索引或 ALTER TABLE ... MOVE 时,申请不到足够大的连续 EXTENT。
实操建议:
- 查当前对象最常申请的
EXTENT大小:看DBA_SEGMENTS.INITIAL_EXTENT和NEXT_EXTENT分布,再对比DBA_FREE_SPACE中大于该值的块数量 - 模拟一次分配:用
SELECT COUNT(*) FROM DBA_FREE_SPACE WHERE TABLESPACE_NAME = 'USERS' AND BYTES >= 1048576(假设要 1MB 连续块) - 如果结果为 0,且近期出现
ORA-01653(无法扩展表)或ORA-01654(无法扩展索引),才说明碎片已实质影响运行
ASSM 表空间下 DBA_FREE_SPACE 的局限性
在 EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO(即 ASSM)下,DBA_FREE_SPACE 只反映完全空的 Extent,不体现段内 bitmap 管理的“半满块”。这意味着:即使 DBA_FREE_SPACE 显示空闲充足,仍可能因高水位线(HWM)上无足够空块导致插入慢或触发延迟块清除。
实操建议:
- ASSM 下别单靠
DBA_FREE_SPACE判断碎片,补查DBA_SEGMENTS.BLOCKS - DBA_SEGMENTS.EMPTY_BLOCKS(后者在 ASSM 中恒为 0,所以无效)→ 改用DBMS_SPACE.SPACE_USAGE获取真实段内使用率 -
DBA_FREE_SPACE在 ASSM 中的BYTES可能比实际略大(因 Extent 头部开销未扣除),但误差一般 - 如果表空间启用了
SEGMENT ADVISORY,直接查DBA_ADVISOR_FINDINGS里关于 “Tablespace Fragmentation” 的建议更省事
碎片分析不是跑个 SQL 就完事的事。最易被忽略的,是没把查询结果和实际业务 DDL/DML 模式对齐——比如 OLAP 系统批量建大分区表,却拿 OLTP 小对象的碎片阈值去评估,结论自然失效。










