使用STORE IN时Oracle无法轮询分区的原因排查
问题分析与解决
问题现象
在Oracle Database 19c环境中,将原本单表空间、按天区间分区的表,通过以下语句设置新分区轮询分布到多个表空间:
alter table TABLE_NAME set STORE IN(TABLESPACE_1, TABLESPACE_2, TABLESPACE_3)
初始配置正常工作,但启用删除N天前旧分区的清理脚本后,分区轮询分配机制失效,新分区持续创建在上一个分区所在的表空间中。通过保留一个永不删除的只读锚定分区可解决此问题,需明确原因及排查方法。
测试复现(Oracle 18c)
创建测试表
create table rr_test (stringCol VARCHAR2(19 BYTE), UP TIMESTAMP(6)) tablespace ROUND_ROBIN_TEST1 partition by range (UP) interval (numtodsinterval(1, 'DAY')) subpartition by LIST (stringCol) subpartition template (SUBPARTITION "STR01" VALUES ('01'), SUBPARTITION "STR02" values ('02')) (partition P1 values less than (timestamp '2021-07-21 00:00:00'));
插入初始数据生成分区
INSERT into rr_test VALUES('01', TIMESTAMP '2021-09-21 00:00:00'); INSERT into rr_test VALUES('02', TIMESTAMP '2021-09-22 00:00:00'); INSERT into rr_test VALUES('02', TIMESTAMP '2021-09-23 00:00:00');
设置分区轮询表空间
alter table rr_test set store in (ROUND_ROBIN_TEST1, ROUND_ROBIN_TEST2, ROUND_ROBIN_TEST3);
插入数据生成轮询分区
INSERT into rr_test VALUES('01', TIMESTAMP '2021-09-24 00:00:00'); INSERT into rr_test VALUES('02', TIMESTAMP '2021-09-25 00:00:00'); INSERT into rr_test VALUES('01', TIMESTAMP '2021-09-26 00:00:00');
删除旧分区
alter table rr_test drop partition P1; INSERT into rr_test VALUES('01', TIMESTAMP '2021-09-27 00:00:00'); alter table rr_test drop partition for (TIMESTAMP'2021-09-20 00:00:00'); INSERT into rr_test VALUES('02', TIMESTAMP '2021-09-28 00:00:00'); alter table rr_test drop partition for (TIMESTAMP'2021-09-21 00:00:00'); INSERT into rr_test VALUES('01', TIMESTAMP '2021-09-29 00:00:00');
查询分区表空间分配结果
select * from user_tab_partitions where table_name = 'RR_TEST';
查询结果显示删除分区后新分区停止轮询:
RR_TEST SYS_P9280 TIMESTAMP' 2021-09-24 00:00:00' ROUND_ROBIN_TEST1 RR_TEST SYS_P9283 TIMESTAMP' 2021-09-25 00:00:00' ROUND_ROBIN_TEST1 RR_TEST SYS_P9286 TIMESTAMP' 2021-09-26 00:00:00' ROUND_ROBIN_TEST2 RR_TEST SYS_P9289 TIMESTAMP' 2021-09-27 00:00:00' ROUND_ROBIN_TEST3 RR_TEST SYS_P9292 TIMESTAMP' 2021-09-28 00:00:00' ROUND_ROBIN_TEST1 RR_TEST SYS_P9295 TIMESTAMP' 2021-09-29 00:00:00' ROUND_ROBIN_TEST1 RR_TEST SYS_P9298 TIMESTAMP' 2021-09-30 00:00:00' ROUND_ROBIN_TEST1
原因解析
Oracle区间分区的轮询表空间分配,依赖表中存在的最后一个分区(或锚定分区)确定下一个分区的表空间序列位置。当所有初始分区(包括建表时指定的第一个分区P1)被删除后,Oracle无法找到计算轮询序列的基准分区,导致后续新分区默认复用最后一次使用的表空间,不再执行轮询逻辑。
保留永不删除的锚定分区时,Oracle能持续以该分区为基准,按照STORE IN指定的表空间列表顺序计算下一个分区的目标表空间,维持轮询机制正常运行。
深入排查方法
查看分区元数据
查询分区的表空间分配顺序及最后一个存在的分区信息:SELECT partition_name, tablespace_name, high_value FROM user_tab_partitions WHERE table_name = 'RR_TEST' ORDER BY high_value;检查表的分区属性
确认STORE IN配置是否生效:SELECT store_in_clause FROM user_part_tables WHERE table_name = 'RR_TEST';追踪分区创建过程
启用10046事件追踪分区创建逻辑,分析trace文件查找表空间选择日志:ALTER SESSION SET EVENTS '10046 trace name context forever, level 4'; -- 执行插入触发分区创建 INSERT into rr_test VALUES('01', TIMESTAMP '2021-10-01 00:00:00'); ALTER SESSION SET EVENTS '10046 trace name context off';验证版本补丁
该问题可能为Oracle已知Bug,检查Oracle Support文档,确认当前19c版本是否存在相关Bug及对应补丁。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

