BasicFiles LOB 不支持 SHRINK SPACE,执行会报 ORA-43852;Oracle 自11g起仅允许 SECUREFILE LOB 使用该功能,BasicFiles 因底层无收缩段管理结构而被硬性禁止。

BasicFiles LOB 不支持 SHRINK SPACE,强行执行会报 ORA-43852 —— 这不是操作姿势问题,是 Oracle 明确禁止的硬限制。
为什么 ALTER TABLE ... SHRINK SPACE 对 BasicFiles LOB 完全无效
Oracle 从 11g 起就将 SHRINK SPACE 的能力限定在 SECUREFILE LOB 上;BasicFiles 是旧架构,底层不维护可收缩的段管理结构。你执行 ALTER TABLE t1 SHRINK SPACE CASCADE 或 MODIFY LOB (col) (SHRINK SPACE),只要 LOB 是 BASICFILE 类型,就会直接报错:ORA-43852: BasicFile LOBs do not support shrink space。这不是权限、表空间或行移动的问题,是类型本身不兼容。
- 查证方式:运行
SELECT securefile FROM dba_lobs WHERE table_name = 'T1' AND column_name = 'LOB_COL',返回NO即确认为 BasicFiles - 哪怕表空间启用了 ASSM、已开启
ENABLE ROW MOVEMENT,也毫无作用 - 试图用
DBMS_SPACE.SPACE_USAGE查碎片率?BasicFiles 没有该视图支持的内部统计维度
唯一可行路径:MOVE + REBUILD,但必须预留额外空间
BasicFiles LOB 收缩本质是“重建”,不是“整理”。核心动作是把数据从旧 LOB 段物理复制到新段,再丢弃旧段。这需要临时双倍空间 —— 原 LOB 段大小 + 新 LOB 段大小,且期间不能有 DML 干扰。
- 非分区表:执行
ALTER TABLE t1 MOVE LOB (lob_col) STORE AS (TABLESPACE new_ts),指定新表空间(或原表空间,但需确保空闲空间 ≥ 当前 LOB 段大小) - 分区表:必须对每个分区单独操作,例如
ALTER TABLE t1 MOVE PARTITION p1 LOB (lob_col) STORE AS (TABLESPACE new_ts) - MOVE 后索引会失效,必须立刻执行
ALTER INDEX idx_name REBUILD ONLINE(若支持 ONLINE)或离线重建 - MOVE 过程中,LOB 列不可被读写;建议在维护窗口执行,并提前 kill 掉持有该 LOB locator 的长事务(查
V$LOB和V$SESSION_LONGOPS)
迁移前先判断:真需要收缩 BasicFiles 吗?
BasicFiles 的空间膨胀往往不是“碎片”导致,而是 PCTVERSION 或长期未提交事务锁住旧版本块。直接 MOVE 成本高,不如先治本:
- 检查是否设置了过高的
PCTVERSION(如 30),改小到 10 或 5:ALTER TABLE t1 MODIFY LOB (lob_col) (PCTVERSION 10) - 确认无长时间未提交的 LOB 写事务(
SELECT sid, sql_id, event FROM v$session WHERE event LIKE '%lob%') - 如果表已升级到 19c 且业务允许,优先考虑整体迁移到 SECUREFILE:
ALTER TABLE t1 MOVE LOB (lob_col) STORE AS SECUREFILE,后续就能用SHRINK SPACE灵活管理
真正难的从来不是敲哪条命令,而是区分“空间没释放”是因为 LOB 类型卡死、还是因为事务/参数/缓存掩盖了真实水位 —— 尤其当 DBA_SEGMENTS.BLOCKS 没变时,别急着 MOVE,先查 V$LOB 和未提交事务。


















