SECUREFILE LOB 必须显式收缩,SHRINK SPACE CASCADE 不处理 LOB 段;需用 ALTER TABLE t MODIFY PARTITION p1 MODIFY LOB (lob_col) (SHRINK SPACE),且前提为 securefile= YES 且表空间段管理为 AUTO。

SECUREFILE LOB 必须单独显式收缩,不能靠 SHRINK SPACE CASCADE
执行 ALTER TABLE t SHRINK SPACE CASCADE 后发现 LOB 段大小没变,不是命令写错了,是 Oracle 明确设计为“跳过 LOB”。哪怕表里只有一个 SECUREFILE LOB 列,它也不会被连带处理。常见误判是查 DBA_SEGMENTS 看到 LOB 段 bytes 不变,就以为整个收缩失败——其实普通表段可能已成功收缩,只是 LOB 段完全没动。
分区表下,SHRINK SPACE 默认只作用于表段本身,不触及其任何分区或 LOB 子段。想收缩某个分区里的 LOB 数据,必须定位到具体分区 + 具体 LOB 列,再用 MODIFY LOB 语法。
- 不能对分区表直接写
ALTER TABLE t SHRINK SPACE CASCADE期望一并处理 LOB - 也不能写
ALTER TABLE t MODIFY PARTITION p1 SHRINK SPACE CASCADE SECUREFILE LOB—— 这种语法不存在,会报 ORA-00900 - 正确路径是:先确认分区名和 LOB 列名,再执行
ALTER TABLE t MODIFY PARTITION p1 MODIFY LOB (lob_col) (SHRINK SPACE)
收缩前必须验证两个硬性前提
缺一不可,否则命令直接报错或静默无效:
- 查
DBA_LOBS:确认目标列的securefile值为YES,且tablespace_name在DBA_TABLESPACES中的segment_space_management为AUTO - BASICFILE LOB 完全不支持
SHRINK SPACE,19c 中强行执行会报ORA-43852;若发现是 BASICFILE,只能重建:用MOVE PARTITION+REBUILD INDEX,且需额外 1 倍空间 -
ENABLE ROW MOVEMENT对 LOB 收缩无影响,不用开也不用关
收缩命令语法细节决定锁时长与效果
ALTER TABLE t MODIFY PARTITION p1 MODIFY LOB (lob_col) (SHRINK SPACE) 是标准写法,括号位置不能省略。后缀选择直接影响业务影响:
-
SHRINK SPACE COMPACT:只重组 LOB 数据块,不调高水位线(HWM),锁时间短,适合高峰期分步操作 -
SHRINK SPACE(无后缀):重组 + 调整 HWM,释放空间立竿见影,但需短暂独占锁,期间阻塞对该 LOB 列的所有读写 - 不支持
CASCADE,加了会报ORA-30871
注意:该命令不支持跨分区隐式生效,每个分区 + 每个 LOB 列都得单独执行一次。
验证是否真收缩成功,别信 DBA_SEGMENTS.bytes
DBA_SEGMENTS.bytes 更新有延迟,且 LOB 段可能被缓存;最可靠方法是对比收缩前后:
- 从
DBA_LOBS.segment_name查出 LOB 段名(形如SYS_LOB00000XXXX$$) - 执行
SELECT segment_name, blocks FROM dba_segments WHERE segment_name = 'SYS_LOB00000XXXX$$' -
blocks值变小才算成功 - 若仍没变化,大概率是 LOB 数据实际碎片率低,或存在未提交事务 / 长时间打开的 LOB locator(查
V$LOB和V$SESSION_LONGOPS)
真正难的不是敲那条命令,而是判断该不该收缩、什么时候收缩、收缩后要不要立刻 RESIZE 数据文件——这些没法靠一条 SQL 解决。


















