shrink space compact 不释放空间,因为它只重组数据块内行、消除行迁移和碎片,但不移动高水位线(HWM);适用于OLTP高负载场景,需配合 shrink space 才能真正释放空间。
为什么 shrink space compact 不释放空间但还要用它
因为 shrink space compact 只做数据块内重组(把散落的行往空闲块里挪),不移动高水位线(hwm),所以表段占用的磁盘空间不会变小。但它能消除行迁移、压缩块内碎片,让后续全表扫描逻辑读下降——这在业务高峰期特别关键。
常见错误现象:执行完 shrink space compact 后查 dba_segments.bytes 没变化,以为命令失败;其实它根本就不是用来“释放空间”的。
- 适用场景:OLTP 系统负载高、不能容忍短时锁表或空间回收抖动
- 性能影响:仅对涉及的数据块加行级锁,几乎不影响并发 DML
- 后续必须补一句
alter table tbname shrink space才能真正降低 HWM、归还空间
执行前必须检查的三个硬性条件
shrink space compact 不是所有表都能跑,缺一不可:
- 表已启用行迁移:
alter table tbname enable row movement—— 否则报ORA-10631: SHRINK clause not allowed for this object - 所在表空间段管理方式为
AUTO(自动段空间管理):查dba_tablespaces.segment_space_management,值必须是AUTO,MANUAL会直接报错 - 表类型是堆表(heap table):IOT、簇表、含
LONG列的表、函数索引依赖的表,都不支持
注意:enable row movement 会让依赖该表的视图/存储过程失效,建议执行后顺手跑一遍 @?/rdbms/admin/utlrp.sql 编译无效对象。
compact 和 cascade 的实际效果差异
compact 和 cascade 是正交选项,可以组合使用,但含义不同:
-
shrink space compact:只整理表数据块,不动索引,HWM 不动 -
shrink space cascade:整理表 + 所有相关索引(非唯一索引、分区索引等),并移动 HWM;但会锁索引段,时间略长 -
shrink space compact cascade:先紧凑表和索引(不移 HWM),适合高负载期分步操作
典型误用:对大表直接用 shrink space cascade,结果索引重建耗时过长,触发长时间 DML 阻塞。更稳妥的做法是先 compact,再择机 shrink space 单独收尾。
收缩后空间没变小?别急着怀疑命令
执行完 shrink space compact,dba_segments.bytes 不变、dba_free_space 也不涨,完全正常。这是设计使然,不是 bug。
真正释放空间要靠第二步:alter table tbname shrink space(不带参数)或 shrink space cascade。这两条才会触发 DDL 级别的 HWM 下移和空间回收。
容易被忽略的点:即使你只关心性能(比如降低全表扫描逻辑读),也得确认是否真的需要释放磁盘空间。如果表空间本身没紧张,compact 就够了;否则漏掉第二步,等于白干。











