能回收,但必须满足三个硬性前提:表空间是本地管理+启用assm+表已开启行移动;不满足任一条件,shrink space会报错或静默失败。
能回收,但必须满足三个硬性前提:表空间是本地管理+启用assm+表已开启行移动。不满足任一条件,shrink space 会报错或静默失败。
为什么 SHRINK SPACE 在某些表上执行没反应?
常见现象是执行 ALTER TABLE t1 SHRINK SPACE 后,DBA_SEGMENTS.bytes 不变,HWM 也没动。根本原因通常是:
- 表所在表空间不是本地管理(
extent_management = 'LOCAL'),或者没启用自动段空间管理(segment_space_management = 'AUTO') - 表未启用行移动:
ALTER TABLE t1 ENABLE ROW MOVEMENT没执行过 - 表含 LONG、BFILE、函数索引、位图连接索引等 Oracle 明确不支持收缩的对象类型
SHRINK SPACE 的三种模式怎么选?
SHRINK SPACE 后可跟 COMPACT、CASCADE 或不加参数,行为差异极大:
-
SHRINK SPACE COMPACT:只做数据重组(第一阶段),不调 HWM;适合高峰期“先整理再择机收缩”,锁表时间极短 -
SHRINK SPACE(无后缀):完成全部两阶段——重组 + 调整 HWM;需瞬时 X 锁,阻塞 DML,但释放空间立竿见影 -
SHRINK SPACE CASCADE:在上一条基础上,连带收缩该表所有相关索引段;注意:对分区表的 LOB 列无效,SECUREFILE LOB 需单独执行ALTER TABLE ... MODIFY LOB (...) (SHRINK SPACE)
分区表和 LOB 段要特别处理
普通表收缩完就收工,但分区表和 LOB 往往留尾巴:
- 分区表不能直接
SHRINK SPACE整个表,必须指定分区:ALTER TABLE t1 MODIFY PARTITION p202406 SHRINK SPACE CASCADE - BASICFILE LOB 在 19c 完全不支持
SHRINK,只能用MOVE PARTITION+REBUILD INDEX,且需额外空间 - SECUREFILE LOB 必须单独处理,
SHRINK SPACE CASCADE会跳过它;查空间用DBMS_SPACE.SPACE_USAGE,收缩用ALTER TABLE t1 MODIFY LOB (c1) (SHRINK SPACE)
最易被忽略的一点:v$segment_statistics 或 DBA_SEGMENTS 看不到实时 HWM 变化,得查 DBA_TABLES.blocks 和 empty_blocks 差值,或用 ANALYZE TABLE t1 COMPUTE STATISTICS(不推荐生产环境);更稳妥的是对比收缩前后 SELECT segment_name, blocks FROM dba_segments WHERE segment_name = 'T1' ——这个值变小了,才算真收缩成功。











