必须先执行alter table enable row movement,否则shrink space会因ora-10636报错失败;还需确保表空间为assm模式、显式处理lob列,并区分shrink space compact(仅整理数据)与shrink space(真正降hwm释放空间)。

执行 ALTER TABLE ... SHRINK SPACE 前没开 ROW MOVEMENT
这是最常见、最直接的失败原因。Oracle 要移动行(把后面的数据往前挪),必须允许行物理位置变更,否则 SHRINK SPACE 会报错:ORA-10636: row movement is not enabled。
不是“建议开启”,而是硬性前提——没这句,命令根本跑不起来。
操作必须分两步:
ALTER TABLE table_name ENABLE ROW MOVEMENT;ALTER TABLE table_name SHRINK SPACE;
注意:ENABLE ROW MOVEMENT 会让基于 ROWID 的触发器失效,也会让游标失效(需重新 parse),生产环境执行前得评估应用兼容性。
SHRINK SPACE 在非 ASSM 表空间上直接报错
ASSM(Automatic Segment Space Management)是硬门槛。如果表所在表空间是手动段管理(MSSM),执行 SHRINK SPACE 会立刻失败:ORA-10635: Invalid segment or tablespace type。
查表空间类型用:
SELECT tablespace_name, segment_space_management FROM dba_tablespaces WHERE tablespace_name = 'YOUR_TS_NAME';
返回 MANUAL 就不能用 SHRINK;只有 AUTO 才行。迁移方案只能是先 CREATE TABLESPACE ... SEGMENT SPACE MANAGEMENT AUTO,再 MOVE 表过去,或者换其他方法(如 MOVE + 重建索引)。
SHRINK SPACE COMPACT 不等于降 HWM
很多人执行了 SHRINK SPACE COMPACT 就以为完事了,但其实它只做了第一阶段:数据紧凑(compact),把空洞里的行往前拉,并不移动高水位线。HWM 还卡在老位置,空间没真正释放给表空间。
真正释放磁盘空间、降低 HWM 的,是第二步:
-
SHRINK SPACE(隐含COMPACT+RESET HWM) - 或显式执行
SHRINK SPACE CASCADE(连带索引一起收缩)
但第二步需要短暂加表级排他锁(X lock),DML 会阻塞。业务高峰期执行,可能引发超时或事务回滚。
LOB 列未显式处理导致 SHRINK 失败或异常
表里有 CLOB/BLOB 列时,SHRINK SPACE 默认不处理 LOB 段——它会跳过,但不报错,结果是主表 HWM 降了,LOB 段仍占着大量空间,整体空间回收效果极差。
正确做法是显式指定 LOB 子句:
ALTER TABLE t SHRINK SPACE CASCADE LOB (lob_col) STORE AS (TABLESPACE ts_name);
否则,LOB 数据可能被误写入 SYSTEM 或 SYSAUX 表空间(尤其在没指定 STORE AS 且默认表空间受限时),后果严重。
查是否有 LOB 列:
SELECT column_name, data_type FROM user_tab_columns WHERE table_name = 'T' AND data_type LIKE '%LOB%';
真正影响空间释放的,从来不是命令敲得对不对,而是执行前有没有看清表空间类型、LOB 结构、锁影响范围这三个实际约束。漏掉任意一个,SHRINK SPACE 就只是个看起来在动、其实没效果的操作。











