ALTER TABLESPACE COALESCE 仅对字典管理表空间(EXTENT_MANAGEMENT = 'DICTIONARY')有效,且仅合并同一数据文件内物理首尾相接的空闲区;本地管理表空间执行该命令无任何效果。

ALTER TABLESPACE COALESCE 在什么情况下真有用
它只对字典管理表空间(EXTENT_MANAGEMENT = 'DICTIONARY')有效,且仅合并同一数据文件内物理首尾相接的空闲 EXTENT。本地管理表空间(LMT)执行该命令完全静默、无任何效果——不是慢,是根本没跑。
常见错误现象:ALTER TABLESPACE users COALESCE; 执行后 DBA_FREE_SPACE 行数不变,MAX(bytes) 也没变大,还以为命令失败或权限不足。
- 必须先查确认类型:
SELECT TABLESPACE_NAME, EXTENT_MANAGEMENT FROM DBA_TABLESPACES WHERE TABLESPACE_NAME = 'USERS';—— 结果是DICTIONARY才继续 - 手动执行前,检查当前空闲结构:
SELECT FILE_ID, BLOCK_ID, BYTES FROM DBA_FREE_SPACE WHERE TABLESPACE_NAME = 'USERS' ORDER BY FILE_ID, BLOCK_ID;—— 肉眼扫一遍,相邻行的BLOCK_ID + BLOCKS是否等于下一行的BLOCK_ID - 如果表空间启用了
PCTINCREASE != 0,SMON 每 5 分钟会自动触发一次 coalesce;设为 0 则自动合并彻底关闭
为什么你执行了 COALESCE 却没看到变化
最常见原因是:你以为的“连续”,Oracle 不认。它只认物理块地址严格衔接,中间差哪怕 1 个 block,就断开。而且它不跨数据文件——FILE_ID 不同的空闲区,永远不合并。
典型误判场景:DBA_FREE_SPACE 返回 200+ 行,你直接跑 COALESCE,结果发现行数还是 200+。其实这些空闲区被已分配的 EXTENT 隔开了,或者分布在多个文件里。
- 执行后唯一可靠验证方式:
SELECT COUNT(*) FROM DBA_FREE_SPACE WHERE TABLESPACE_NAME = 'USERS';和SELECT MAX(BYTES) FROM DBA_FREE_SPACE WHERE TABLESPACE_NAME = 'USERS';—— 两项都变小/变大才算生效 - 别看
sum(bytes),那只是总量;碎片问题看的是最大单块MAX(bytes)是否足够支撑你要建的段(比如建索引要 8MB,但最大空闲才 64KB,COALESCE再勤也救不了) - 在 ASSM(
SEGMENT_SPACE_MANAGEMENT = 'AUTO')表空间上反复执行COALESCE,只会增加 SQL 解析开销,无任何空间收益
比 COALESCE 更有效的碎片应对方式
当 DBA_FREE_SPACE 行数 > 200 或 MAX(bytes) 远低于需求时,说明碎片已影响分配。此时 COALESCE 大概率是徒劳,得动对象级操作。
- 对大表:先
ALTER TABLE t ENABLE ROW MOVEMENT;,再ALTER TABLE t SHRINK SPACE COMPACT;—— 降低 HWM,把数据往前提,腾出尾部连续空间 - 索引碎片:用
ALTER INDEX i REBUILD ONLINE;,尤其对高频更新的索引,能减少叶子块分裂和逻辑碎片 - 极端情况(如日志表频繁 delete + insert 导致位图混乱):导出关键数据 →
TRUNCATE→ 重导入,或用DBMS_REDEFINITION在线重定义 - 别盲目换回 MSSM(手动段管理):虽然它让
COALESCE生效,但失去 ASSM 的并发优势,且需人工维护 freelists,维护成本更高
执行前必须盯住的三个硬条件
COALESCE 看似简单,但跳过检查基本白跑,还可能引发锁等待。它不报错,但会短暂持有数据文件级 ST 锁,业务高峰期执行容易卡住其他空间申请。
- 确认表空间类型是
DICTIONARY,且分配类型是UNIFORM(AUTOALLOCATE在 DMT 下不合法,查ALLOCATION_TYPE字段) - 确认当前空闲区间数量确实多(
COUNT(*) > 50),且MAX(BYTES)明显偏小(比如小于 1MB,而你常建的对象需要 4MB+) - 避开业务高峰执行;若表空间正在被大量 DML 使用,SMON 可能无法及时完成合并,导致锁等待时间延长
真正难的不是命令怎么写,而是判断“要不要用”——多数生产环境的所谓碎片,根源不在空闲区分散,而在对象生命周期管理缺失或应用批量删除后未 shrink。盯着 DBA_FREE_SPACE 行数和 MAX(bytes) 两个数字,比反复执行 COALESCE 有用得多。


















