Oracle交换分区报ORA-14095错误的解决方法咨询
报错原因
ORA-14095: ALTER TABLE EXCHANGE requires a non-partitioned, non-clustered table的触发原因是Oracle分区交换的基础语法限制:
- 所有Oracle版本通用的
EXCHANGE PARTITION语法,仅支持将分区表的单个分区与一个非分区表做数据段指针互换,不支持直接在两个分区表的单个分区之间直接做交换。 - 你当前执行的语句中,
WITH TABLE后传入的ADS.test_table_2本身是列表分区表,不符合语法对交换对象的要求,因此直接报错。
正确操作步骤
要实现两个分区表的单个分区数据互换,需要先创建一个和两张业务表结构完全一致的非分区中转表,通过三次段交换完成需求,整个过程仅修改数据段指针,不会产生大量数据IO,执行速度极快:
- 创建非分区中转临时表,字段、类型、约束、默认值、表空间必须和两张业务表完全匹配:
CREATE TABLE ADS.test_table_exchange_temp ( report_month DATE, name VARCHAR2(128) ) TABLESPACE TEST_TABLESPACE; -- 如果业务表有索引、约束,需要在中转表上创建完全匹配的普通索引、约束,避免交换后索引失效或触发报错
- 第一次交换:将TEST_TABLE_2的目标分区数据交换到中转表
ALTER TABLE ADS.test_table_2 EXCHANGE PARTITION TEST_PART_2022_05_31 WITH TABLE ADS.test_table_exchange_temp -- 提前确认数据合规可以使用WITHOUT VALIDATION提升大分区交换速度 WITHOUT VALIDATION -- 存在全局索引时加上该子句自动维护索引,避免索引失效 UPDATE GLOBAL INDEXES;
执行完成后,TEST_TABLE_2的TEST_PART_2022_05_31分区为空,中转表存储原TEST_TABLE_2该分区的全量数据。
3. 第二次交换:将TEST_TABLE_1的目标分区数据交换到中转表
ALTER TABLE ADS.test_table_1 EXCHANGE PARTITION TEST_PART_2022_05_31 WITH TABLE ADS.test_table_exchange_temp WITHOUT VALIDATION UPDATE GLOBAL INDEXES;
执行完成后,TEST_TABLE_1的TEST_PART_2022_05_31分区存储原TEST_TABLE_2该分区的数据,中转表存储原TEST_TABLE_1该分区的全量数据。
4. 第三次交换:将中转表存储的原TEST_TABLE_1分区数据交换到TEST_TABLE_2的目标分区
ALTER TABLE ADS.test_table_2 EXCHANGE PARTITION TEST_PART_2022_05_31 WITH TABLE ADS.test_table_exchange_temp WITHOUT VALIDATION UPDATE GLOBAL INDEXES;
执行完成后,TEST_TABLE_2的TEST_PART_2022_05_31分区存储原TEST_TABLE_1该分区的数据,中转表回到空状态,两个分区的互换完成。
5. 确认数据无误后,可以删除中转临时表:
DROP TABLE ADS.test_table_exchange_temp PURGE;
注意事项
- 中转表结构必须和业务表完全一致,包括字段顺序、类型长度、非空约束、默认值,否则会触发
ORA-14097列定义不匹配报错。 - 分区交换是DDL操作,执行后会自动提交当前事务,操作前请确认无未提交的业务写入,尽量在业务低峰期执行。
- 你场景中两个分区的分区键取值规则完全一致(均为
2022-05-31),使用WITHOUT VALIDATION不会产生数据不符合分区规则的问题,可放心使用以提升性能。
内容的提问来源于stack exchange,提问作者Asli
相关产品推荐
相关产品推荐

