TRUNCATE PARTITION 不会触发 INTERVAL 分区自动收缩,因其仅清空数据、重置 HWM 并保留分区定义;Oracle 19c 的 INTERVAL 分区无自动收缩机制,仅支持自动新增,收缩分区数量必须显式执行 DROP PARTITION。
TRUNCATE PARTITION 不会触发 INTERVAL 分区的自动收缩
oracle 19c 的 interval 分区表在执行 truncate partition 后,对应分区的数据被清空、hwm 归零,但分区定义仍保留在数据字典中——这本身不是 bug,而是设计行为。关键点在于:truncate partition 不删除分区,只重置内容,因此不会触发任何“收缩”逻辑,更不会让 oracle 自动合并或移除空分区。
INTERVAL 分区没有“自动收缩”机制
Oracle 官方从未提供 INTERVAL 分区的自动收缩能力。所谓“自动”,仅指新增分区时按 INTERVAL 表达式自动创建(如 NUMTOYMINTERVAL(1, 'MONTH')),但反向操作(删/合空分区)完全不支持。你看到的“分区还在”,不是残留,是它本该就在。
-
DBA_TAB_PARTITIONS中该分区的NUM_ROWS为 0、BLOCKS接近 0,说明空间已释放,但段(segment)未被 DROP - 即使连续
TRUNCATE多个旧分区,也不会触发自动DROP或COALESCE - 想真正减少分区数量,必须显式执行
DROP PARTITION,且需加UPDATE GLOBAL INDEXES(若存在全局索引)
为什么不能靠 SHRINK SPACE 解决?
SHRINK SPACE 对单个 INTERVAL 分区有效(如 ALTER TABLE t MODIFY PARTITION p202401 SHRINK SPACE),但它只压缩该分区内部的 HWM 和碎片,不改变分区总数,也不影响 INTERVAL 元数据。更重要的是:
- 如果该分区含
SECUREFILE LOB列,SHRINK SPACE CASCADE会跳过 LOB 段,需单独执行ALTER TABLE t MODIFY LOB (col) (SHRINK SPACE) -
BASICFILE LOB在 19c 中根本不支持SHRINK,只能用MOVE PARTITION,但会锁分区且需额外空间 -
SHRINK前必须确保ENABLE ROW MOVEMENT已开启,否则报错ORA-10636
真正要收缩分区数量,只能手动 DROP
如果你的目标是减少分区数(比如清理掉 2022 年前所有空分区),唯一办法是逐个 DROP PARTITION。注意顺序和依赖:
- 先确认无活跃事务访问:检查
v$session和v$sql中是否还有涉及该分区的 SQL - 若有全局索引,必须加
UPDATE GLOBAL INDEXES,否则索引变UNUSABLE,后续查询直接报ORA-01502 - 执行后立即查
DBA_IND_STATISTICS,确认全局索引状态;若出现ORPHANED_ENTRIES,低峰期手动运行DBMS_PART.CLEANUP_GIDX - 不要依赖
DBMS_SCHEDULER自动跑清理作业——它的默认窗口可能错过业务低峰,且不保证一次清完
最易被忽略的一点:INTERVAL 分区的 HIGH_VALUE 是动态计算的,DROP 最老分区后,新插入数据仍按原 INTERVAL 规则生成下一个分区,不会“回填”空档。收缩分区数量 ≠ 改变分区策略,这两件事必须分开处理。











