1818IP-服务器技术教程,云服务器评测推荐,服务器系统排错处理,环境搭建,攻击防护等

当前位置:首页 - 数据库 - 正文

君子好学,自强不息!

Oracle分区数据问题的分析和修复

2022-11-22 | 数据库 | gtxyzz | 509°c
A+ A-

今天根据同事的反馈,处理了一个分区表的问题,也让我对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:insertedpartitionkeydoesnotmaptoanypartition

而如果把‘pz’修改为另外一个字符串’dhsh’就没问题。

所以这样一个ORA问题,通过初始信息我得到一个基本的推论,那就是没有符合条件的分区了。而如果仔细分析,会发现这个问题似乎有些蹊跷。

一般的分区表都是Range分区,基本就是数值范围或者是日期来做范围分区,这个问题该怎么理解呢,如果按照时间分区,那么另外一个SQL插入也应该失败才对。

所以带着疑惑,我查看了分区的情况,发现这个表竟然有默认键值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的格式,我们是要想修改template的子分区模板规则。

altertableTLSTAT_NEWBG.DY_USER_ANALYSIS_MIN
setSUBPARTITIONTEMPLATE(
SUBPARTITION"SP_ABC"values('abc')
TABLESPACE"TEST_DATA",
。。。
SUBPARTITION"SP_OTHER"values('xjzj','hij','pz’)
TABLESPACE"TEST_DATA")

按照这种方式修改模板就没有问题了,然后继续尝试插入数据,发现还是同样的错误。这个时候是哪里的问题了呢。

根据错误反复排查,还是指向了分区的定义,那么我们看看其中一个分区的情况。

(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"),

所以按照分区的定义,里面还是少了这个subpartition的数值范围信息。

如果想重新生成一个新的subpartition可以使用如下的方式:

ALTERTABLETLSTAT_NEWBG.DY_USER_ANALYSIS_MINMODIFYPARTITIONP_OLDaddSUBPARTITIONP_OLD_SP_OTHER_pzVALUES('pz');

如果想生成默认的subpartition名称可以使用如下的方式:

ALTERTABLETLSTAT_NEWBG.DY_USER_ANALYSIS_MINMODIFYPARTITIONP2017_Q2addSUBPARTITIONVALUES('pz');

这个时候的subpartition的信息,我摘录出一个来简单看看。

(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"),

如果依旧觉得不满意,我们来使用merge subpartitions的方式,当然这个操作还是会有全局锁的,会把两个分区整合为一个。

ALTERTABLETLSTAT_NEWBG.DY_USER_ANALYSIS_MINMERGESUBPARTITIONSP2017_Q2_SP_OTHER,SYS_SUBP21INTOSUBPARTITIONP2017_Q2_SP_OTHER;

本文来源:1818IP

本文地址:https://www.1818ip.com/post/10812.html

免责声明:本文由用户上传,如有侵权请联系删除!

发表评论

必填

选填

选填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。