oracle 12c 的 merge partition 仅支持一次合并两个相邻的 range 或 list 分区,不支持三个及以上分区或非相邻分区;目标分区必须为源分区之一,需加 update indexes 避免本地索引失效,且不释放存储空间。
oracle 12c 中 merge partition 命令确实能合并两个相邻分区,但它不支持一次合并多个分区(比如三个或以上),也不能跳过中间分区合并非相邻分区。这是很多人误以为“12c 支持多分区合并”的关键误区。
MERGE PARTITION 只允许合并两个相邻范围分区
MERGE PARTITION 的语法本质是「把 A 和 B 合并进 C」,而 C 必须是 A 或 B 之一(即目标分区必须已存在),且 A、B 必须在逻辑上相邻(high_value 连续)。
常见错误现象包括:
- 执行
ALTER TABLE t MERGE PARTITIONS p1,p2,p3 INTO PARTITION p3→ 报错ORA-14054:不支持三个及以上分区名 - 尝试合并
p1和p3(中间缺p2)→ 报错ORA-14055:分区不相邻 - 对 hash 分区表或引用分区表使用该语句 → 报错
ORA-14035:不支持该分区类型
使用场景非常明确:仅适用于 RANGE 或 LIST 类型的一级分区表(不含 composite-hash 子分区),且仅用于清理低水位历史分区(如按月归档后合并 Q1 两个子月分区)。
示例:
ALTER TABLE vast.hepart MERGE PARTITIONS p0, p1 INTO PARTITION p1 UPDATE INDEXES;
注意:
-
UPDATE INDEXES是强烈建议加上的,否则 local 索引分区会变成UNUSABLE,需手动执行ALTER TABLE ... MODIFY PARTITION ... REBUILD UNUSABLE LOCAL INDEXES - global 索引不受影响,但若未加
UPDATE GLOBAL INDEXES(该子句不被MERGE PARTITION支持),则 global 索引会自动维护;不过仍建议验证USER_INDEXES.status是否为VALID
合并多个分区需分步执行,不能“批量”
12c 虽支持 ADD/DROP/TRUNCATE 多个分区,但 MERGE 仍是严格二元操作。想把 p0–p3 四个分区合并成一个,必须:
- 先
MERGE PARTITIONS p0,p1 INTO PARTITION p1 - 再
MERGE PARTITIONS p1,p2 INTO PARTITION p2 - 最后
MERGE PARTITIONS p2,p3 INTO PARTITION p3
每一步都会重写数据、重建 local 索引段、触发日志生成。如果分区数据量大,整个过程不可中断,且没有原子性保障——中途失败,只能人工回退。
性能影响明显:
- 合并 10GB 分区可能耗时数分钟,期间该分区不可写(DDL 锁表)
- high_value 继承规则是取两个源分区中较大的那个,所以最终分区边界不会收缩,只是“腾出空分区名”,后续还得手动
DROP多余的旧分区名(如 p0、p1、p2 实际已不存在,但名字还在 DDL 元数据里?不,它们已被物理删除)
容易踩的坑:误用 UPDATE INDEXES 或忽略索引状态
-
UPDATE INDEXES仅对 local 索引生效,对 global 索引无效(global 索引自动维护,但可能变UNUSABLE如果有其他并发 DDL 干扰) - 不加
UPDATE INDEXES时,local 索引分区状态变为UNUSABLE,但查询仍可走 index fast full scan,只是执行计划可能劣化 - 检查索引是否可用,别只看
USER_INDEXES.status,还要查USER_IND_PARTITIONS.status(尤其对 local 索引)
示例检查语句:
SELECT index_name, status FROM user_indexes WHERE table_name = 'HEPART';
SELECT index_name, partition_name, status FROM user_ind_partitions
WHERE index_name IN ('IDN_HEPART_LNAME');
最常被忽略的一点:MERGE PARTITION 不释放空间。合并后数据物理上仍在原表空间,高水位线(HWM)不会下降,必须配合 ALTER TABLE ... SHRINK SPACE(需行移动启用)或导出/重建才能回收。
合并不是“删数据”,而是“重排数据块”,这点和 TRUNCATE PARTITIONS 完全不同。











