今天根据同事的反馈,处理了一个分区表的问题,也让我对Oracle的分区表功能有了更深入的了解。首先,根据开发同事的反馈,他们在程序中批量插入部分数据的时候,总会有一些请求执行失败,查看日志是ORA-14400的错误。对于这种问题,我有一个很直观的感受,分区有问题。>INSERTINTODY_USER_ANALYSIS_MIN(ID,STAT_TIME,GAME_TYPE,ZONE_ID,GROUP_ID,ONLINE_5CNT)VALUES(100,to_date('2017-07-1217:40:00','yyyy-mm-ddHH24:mi:ss'),'pz',to_number(-1),to_number(-1),to_number(0));INSERTINTODY_USER_ANALYSIS_MIN(ID,STAT_TIME,GAME_TYPE,ZONE_ID,GROUP_ID,ONLINE_5CNT)*ERRORatline1:ORA-14400:insertedpartitionkeydoesnotmaptoanypartitionAndifyouchange'pz'toanother字符串'dhsh'没问题。所以对于这样的ORA问题,我通过初始信息得到一个基本的推断,就是不存在符合条件的分区。而且仔细分析一下,你会发现这个问题好像有点奇怪。一般的分区表是Range分区,基本上就是取值范围或者日期的范围分区。如何理解这个问题?如果分区是基于时间的,那么另一个SQL插入也应该失败。于是带着疑惑,查看了分区情况,发现这张表居然有一个默认key值为maxvlue的分区,所以说指定Range分区不存在似乎有点不合理。如果要解决这个问题,一个直观的地方就是查看表的DDL,可以通过dbms_metadata.get_ddl获取。看到拿到的DDL,我有点懵。开发同学是怎么知道这个list分区的,而且已经用到了这个比较高级的特性,就是Range-list分区。PARTITIONBYRANGE("STAT_TIME")SUBPARTITIONBYLIST("GAME_TYPE")SUBPARTITIONTEMPLATE(SUBPARTITION"SP_ABC"values('abc')TABLESPACE"TEST_DATA",...SUBPARTITION"SP_OTHER"values('xjzj','hij')TABLESPACE"TEST_DATA")(PARTITION"P_OLD"VALUESLESSTHAN(TO_DATE('2015-01-0100:00:00','SYYYY-MM-DDHH24:MI:SS','NLS_CALENDAR=GREGORIAN'))对于这种问题,虽然是还是有点奇怪,不过分区表还是有一些基础的,所以分析起来不会有太大的偏差。根据DDL格式,我们要修改模板的子分区模板规则altertableTLSTAT_NEWBG。DY_USER_ANALYSIS_MINsetSUBPARTITIONTEMPLATE(SUBPARTITION"SP_ABC"values('abc')TABLESPACE"TEST_DATA",...SUBPARTITION"SP_OTHER"values('xjzj','hij','pz')TABLESPACE"TEST_DATA")修改模板没有问题就这样,然后继续尝试insertData,发现还是一样的错误,这时候是什么问题呢,根据错误反复排查,是仍然指向分区的定义,那么我们来看其中一个分区的情况。(PARTITION"P_OLD"VALUESLESSTHAN(TO_DATE('2015-01-0100:00:00','SYYYY-MM-DDHH24:MI:SS','NL_CALENDAR=GREGORIAN'))TABLESPACE"TEST_DATA"(SUBPARTITION"P_OLD_SP_ABC"VALUES('abc')TABLESPACE"TEST_DATA",...SUBPARTITION"P_OLD_SP_OTHER"VALUES('xjzj',hij','pz')TABLESPACE"TEST_DATA"),soaccordingtothedefinitionofthepartition,thevalueofthissubpartitionisstillmissing范围信息。如果想重新生成一个新的subpartition可以使用如下的方式:ALTERTABLETLSTAT_NEWBG.DY_USER_ANALYSIS_MINMODIFYPARTITIONP_OLDaddSUBPARTITIONP_OLD_SP_OTHER_pzVALUES('pz');如果想生成默认的subpartition名称可以使用如下的方式:ALTERTABLETLSTAT_NEWBG.DY_USER_ANALYSIS_MINMODIFYPARTITIONP2017_Q2addSUBPARTITIONVALUES('pz');这个时候Fortheinformationofthesubpartition,Iextractoneforasimplelook.(SUBPARTITION"P2017_Q3_SP_ABC"VALUES('abc')TABLESPACE"TEST_DATA",...SUBPARTITION"P2017_Q3_SP_OTHER"VALUES('xjzj','hij')TABLESPACE"TEST_DATA",SUBPARTITION"SYS_SUBP22"VALUES('pz')TABLESPACE"TEST_DATA"),如果你还觉得不满意,我们当然可以使用合并子分区的方法此操作仍将具有全局锁,并将两个分区合并为一个。ALTERTABLETLSTAT_NEWBG.DY_USER_ANALYSIS_MINMERGESUBPARTITIONSP2017_Q2_SP_OTHER,SYS_SUBP21INTOSUBPARTITIONP2017_Q2_SP_OTHER;
