add partition失败是因为含maxvalue的分区已是逻辑上限,新分区边界无法满足“严格大于最后一分区上限”的要求;必须用split partition将maxvalue分区切分为两个相邻分区。

不能直接对含 MAXVALUE 的 Range 分区执行 ADD PARTITION,必须用 SPLIT PARTITION,否则报错 ORA-14074: partition bound must collate higher than that of the last partition
为什么 ADD PARTITION 会失败?
Oracle 要求新分区的 VALUES LESS THAN 值必须严格大于最后一个分区的上限。而含 MAXVALUE 的分区(如 t_pmax)已是逻辑上限,再加一个分区在语法上不成立。
常见错误现象:
- 执行
ALTER TABLE t ADD PARTITION t_p4 VALUES LESS THAN (40)→ 报ORA-14074 - 误以为只要
40 就合法 —— 实际上 Oracle 不比较数值大小,而是校验分区边界顺序
正确拆分步骤:用 SPLIT PARTITION 替代新增
本质是把原 MAXVALUE 分区“切一刀”,生成两个相邻分区,原分区被替换为前半段,后半段成为新分区。
实操建议:
- 先查清当前最大分区名和表空间:
SELECT partition_name, high_value, tablespace_name FROM user_tab_partitions WHERE table_name = 'P_RANGE_TEST' ORDER BY partition_position DESC - 拆分命令格式固定:
ALTER TABLE p_range_test SPLIT PARTITION t_pmax AT (30) INTO (PARTITION t_p3_new, PARTITION t_pmax) -
AT (30)表示新旧分区以30为界:原t_pmax中id 进入 <code>t_p3_new,id >= 30留在新t_pmax - 务必指定目标表空间(尤其生产环境),避免默认表空间空间不足:
PARTITION t_p3_new TABLESPACE t_hs_message
拆分前后数据分布与索引影响
拆分操作会移动数据行,不是纯元数据变更 —— 所有本地索引自动维护,但全局索引需显式重建或加 UPDATE GLOBAL INDEXES 子句。
关键注意事项:
- 拆分期间,原
MAXVALUE分区处于不可写状态,DML 会阻塞,务必选低峰期执行 - 若表有全局索引,不加
UPDATE GLOBAL INDEXES会导致索引失效,查询可能走全表扫描 - 拆分后,原
t_pmax分区的HIGH_VALUE变为30,新t_pmax的HIGH_VALUE仍为MAXVALUE - 拆分不释放空间,只是重分布;若想回收空间,后续需对原分区执行
SHRINK SPACE
最容易被忽略的点:测试时没验证 INSERT 路由是否正确
拆分完成后,必须立刻验证新数据是否落入预期分区。例如插入 id = 25 和 id = 35,然后查 SELECT partition_name FROM user_tab_partitions p, TABLE(dbms_xplan.display_cursor(null,null,'BASIC')) t WHERE ... 不现实 —— 更快的方式是:
- 执行
INSERT INTO p_range_test VALUES (25, 'X'),再查SELECT * FROM p_range_test PARTITION (t_p3_new) - 执行
INSERT INTO p_range_test VALUES (35, 'Y'),再查SELECT * FROM p_range_test PARTITION (t_pmax) - 漏掉这步,上线后才发现数据全进了旧分区,等于白拆











