当前位置: 首页 > Oracle, oracle 11g > 正文

ORA-14400 inserted partition key does not map to any partition错误

这几天每天都在通宵,白天休息时间很少,身体有些吃不消,还好总监又带了两个DBA过来,白天终于可以好好休息了,正在酒店睡觉,被DBA的电话叫醒,说是遇到了分区不存在导致数据无法插入的错误,那张表是按照时间字段的RANGE分区,使用11g的新特性,自动分区(INTERVAL),一天一个分区,怎么会遇到找不到分区的错误呢?出问题的数据是2015年7月21号的数据,最近也是通宵比较多,一时没反应过来,第一反应是不是闰秒的问题导致的,可是在去现场的路上想了下,7月21号早就过了闰秒的日期了。

到了现场,其他DBA手动添加了分区,解决了数据插不进去的问题,我和DBA说那个分区表是自动扩展分区的,不需要手动维护。怎么会出现这个问题,问他看没看告警日志,然后他一拍大腿,说那张表他DROP后重建的,重建的时候没有指定自动扩展分区,他是使用PLSQL Developer工具右键查看表,查看SQL,使用这个SQL创建的,这个表当时的分区停留在7月21号之前,所以他创建的表只有7月21号之前的分区,7月21号及之后的数据就找不到对应的分区了。

以下模拟下这个过程,先创建分区表ORD_PAY_PART。

SQL> CREATE TABLE "CHGSHS"."ORD_PAY_PART"
  2     (    "ORD_ID" VARCHAR2(40) NOT NULL ENABLE,
  3          "PAY_SEQ" VARCHAR2(5) NOT NULL ENABLE,
  4          "PAY_MNS_CD" VARCHAR2(7) NOT NULL ENABLE,
  5          "PAY_ORD_PTR_CD" VARCHAR2(7) NOT NULL ENABLE,
  6          "PAY_ARR_AMT" NUMBER(21,2) NOT NULL ENABLE,
  7          "PAY_AMT" NUMBER(21,2),
  8          "PAY_DTM" DATE,
  9          "PAY_MNS_RLTD_ID" VARCHAR2(40),
 10          "RFN_AMT" NUMBER(21,2) DEFAULT 0,
 11          "RFN_PSS_AMT" NUMBER(21,2) DEFAULT 0,
 12          "ORG_ORD_ID" VARCHAR2(40) NOT NULL ENABLE,
 13          "ORG_PAY_SEQ" VARCHAR2(5) NOT NULL ENABLE,
 14          "ORG_MNS_CD" VARCHAR2(7) NOT NULL ENABLE,
 15          "INST_ID" VARCHAR2(40) NOT NULL ENABLE,
 16          "INST_DTM" DATE DEFAULT SYSDATE NOT NULL ENABLE,
 17          "MDF_ID" VARCHAR2(40) NOT NULL ENABLE,
 18          "MDF_DTM" DATE DEFAULT SYSDATE NOT NULL ENABLE,
 19           CONSTRAINT "PK_ORD_PAY_1" PRIMARY KEY ("ORD_ID", "PAY_MNS_CD")
 20    USING INDEX 
 21    TABLESPACE "TS_INX_ORD"  ENABLE
 22     ) 
 23    TABLESPACE "TS_ORD"
 24  PARTITION BY RANGE ("MDF_DTM") INTERVAL (NUMTODSINTERVAL(1, 'DAY'))
 25   (PARTITION "P1"  VALUES LESS THAN 
 26  (TO_DATE(' 2013-08-25 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) 
 27  SEGMENT CREATION IMMEDIATE
 28    TABLESPACE "TS_ORD" )
 29  ;

Table created.

插入7月1号之前的数据。

SQL> insert /* +append */ into "CHGSHS"."ORD_PAY_PART" select * from "CHGSHS"."ORD_PAY" where MDF_DTM < to_date('2015-07-01 00:00:00','yyyy-mm-dd hh24:mi:ss');

14414226 rows created.

SQL> commit;

Commit complete.

此时,分区停留在7月1日之前,7月1日之后的分区不存在。使用PLSQL Developer工具查看表并查看的SQL,而不是METADABA DDL操作。这样看到的SQL并不是自带扩展分区的,而是列出了所有的分区。根据查看到的SQL创建分区表。

SQL> drop table chgshs.ORD_PAY_PART purge;

Table dropped.

SQL> create table CHGSHS.ORD_PAY_PART
  2  (
  3    ord_id          VARCHAR2(40) not null,
  4    pay_seq         VARCHAR2(5) not null,
  5    pay_mns_cd      VARCHAR2(7) not null,
  6    pay_ord_ptr_cd  VARCHAR2(7) not null,
  7    pay_arr_amt     NUMBER(21,2) not null,
  8    pay_amt         NUMBER(21,2),
  9    pay_dtm         DATE,
 10    pay_mns_rltd_id VARCHAR2(40),
 11    rfn_amt         NUMBER(21,2) default 0,
 12    rfn_pss_amt     NUMBER(21,2) default 0,
 13    org_ord_id      VARCHAR2(40) not null,
 14    org_pay_seq     VARCHAR2(5) not null,
 15    org_mns_cd      VARCHAR2(7) not null,
 16    inst_id         VARCHAR2(40) not null,
 17    inst_dtm        DATE default SYSDATE not null,
 18    mdf_id          VARCHAR2(40) not null,
 19    mdf_dtm         DATE default SYSDATE not null
 20  )
 21  partition by range (MDF_DTM)
 22  (
 23    partition P1 values less than (TO_DATE(' 2013-08-25 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
 24      tablespace TS_ORD
 25      pctfree 10
 26      initrans 1
 27      maxtrans 255
 28      storage
 29      (
 30        initial 8M
 31        next 1M
 32        minextents 1
 33        maxextents unlimited
 34      ),
 35    partition SYS_P4319 values less than (TO_DATE(' 2013-08-26 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
 36      tablespace TS_ORD
 37      pctfree 10
 38      initrans 1
 39      maxtrans 255
 40      storage
 41      (
 42        initial 8M
 43        next 1M
 44        minextents 1
 45        maxextents unlimited
 46      ),
--由于分区太多,建表的SQL8千多行,此处省略大部分分区相关的代码
8123    partition SYS_P4978 values less than (TO_DATE(' 2015-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
8124      tablespace TS_ORD
8125      pctfree 10
8126      initrans 1
8127      maxtrans 255
8128      storage
8129      (
8130        initial 8M
8131        next 1M
8132        minextents 1
8133        maxextents unlimited
8134      )
8135  );

Table created.

SQL> alter table CHGSHS.ORD_PAY_PART
  2    add constraint PK_ORD_PAY_1 primary key (ORD_ID, PAY_MNS_CD)
  3    using index 
  4    tablespace TS_INX_ORD
  5    pctfree 10
  6    initrans 2
  7    maxtrans 255
  8    storage
  9    (
 10      initial 64K
 11      next 1M
 12      minextents 1
 13      maxextents unlimited
 14    );

Table altered.

从建表的SQL可以看到,此时的表分区停留在7月1号之前,而且没有DEFAULT分区,7月1日之后的数据将插入不进去。

SQL> insert /* +append */ into "CHGSHS"."ORD_PAY_PART" select /* +parallel 8 */ * from "CHGSHS"."ORD_PAY" where MDF_DTM >to_date('2015-07-01 00:00:00','yyyy-mm-dd hh24:mi:ss');
insert /* +append */ into "CHGSHS"."ORD_PAY_PART" select /* +parallel 8 */ * from "CHGSHS"."ORD_PAY" where MDF_DTM >to_date('2015-07-01 00:00:00','yyyy-mm-dd hh24:mi:ss')
                                   *
ERROR at line 1:
ORA-14400: inserted partition key does not map to any partition

手动添加分区之后,可以插入数据。

SQL> alter table CHGSHS.ORD_PAY_PART ADD partition P2 values less than (TO_DATE(' 2015-07-02 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')) tablespace TS_ORD;

Table altered.

SQL> insert /* +append */ into "CHGSHS"."ORD_PAY_PART" select /* +parallel 8 */ * from "CHGSHS"."ORD_PAY" where MDF_DTM >to_date('2015-07-01 00:00:00','yyyy-mm-dd hh24:mi:ss') AND MDF_DTM <to_date('2015-07-02 00:00:00','yyyy-mm-dd hh24:mi:ss');

26120 rows created.

SQL> COMMIT;

Commit complete.

11g可以将分区表修改为字段扩展分区,就不需要手动添加分区了。

SQL> alter table CHGSHS.ORD_PAY_PART set INTERVAL (NUMTODSINTERVAL(1, 'DAY'));

Table altered.

SQL> 
SQL> 
SQL> insert /* +append */ into "CHGSHS"."ORD_PAY_PART" select /* +parallel 8 */ * from "CHGSHS"."ORD_PAY" where MDF_DTM >to_date('2015-07-02 00:00:00','yyyy-mm-dd hh24:mi:ss');

501418 rows created.

SQL> commit;

Commit complete.

如果数据库打开了enable_ddl_logging参数,在告警日志就可以看到扩展分区的信息。

SQL> show parameter enable_ddl_logging

NAME                                 TYPE                   VALUE
------------------------------------ ---------------------- ------------------------------
enable_ddl_logging                   boolean                TRUE

Wed Jul 29 22:14:46 2015
alter table CHGSHS.ORD_PAY_PART set INTERVAL (NUMTODSINTERVAL(1, 'DAY'))
Wed Jul 29 22:15:07 2015
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P4986 (682) VALUES LESS THAN (TO_DATE(' 2015-07-08 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P4987 (680) VALUES LESS THAN (TO_DATE(' 2015-07-06 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P4988 (677) VALUES LESS THAN (TO_DATE(' 2015-07-03 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P4989 (678) VALUES LESS THAN (TO_DATE(' 2015-07-04 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P4990 (697) VALUES LESS THAN (TO_DATE(' 2015-07-23 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P4991 (683) VALUES LESS THAN (TO_DATE(' 2015-07-09 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P4992 (686) VALUES LESS THAN (TO_DATE(' 2015-07-12 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P4993 (681) VALUES LESS THAN (TO_DATE(' 2015-07-07 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P4994 (685) VALUES LESS THAN (TO_DATE(' 2015-07-11 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P4995 (684) VALUES LESS THAN (TO_DATE(' 2015-07-10 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P4996 (679) VALUES LESS THAN (TO_DATE(' 2015-07-05 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P4997 (698) VALUES LESS THAN (TO_DATE(' 2015-07-24 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P4998 (691) VALUES LESS THAN (TO_DATE(' 2015-07-17 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P4999 (689) VALUES LESS THAN (TO_DATE(' 2015-07-15 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P5000 (692) VALUES LESS THAN (TO_DATE(' 2015-07-18 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P5001 (690) VALUES LESS THAN (TO_DATE(' 2015-07-16 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P5002 (693) VALUES LESS THAN (TO_DATE(' 2015-07-19 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P5003 (687) VALUES LESS THAN (TO_DATE(' 2015-07-13 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P5004 (688) VALUES LESS THAN (TO_DATE(' 2015-07-14 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P5005 (699) VALUES LESS THAN (TO_DATE(' 2015-07-25 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P5006 (702) VALUES LESS THAN (TO_DATE(' 2015-07-28 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
TABLE CHGSHS.ORD_PAY_PART: ADDED INTERVAL PARTITION SYS_P5007 (703) VALUES LESS THAN (TO_DATE(' 2015-07-29 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))

11g的这个字段扩展分区还是很方便的,10g的时候通常要写存储过程来扩展分区,11g自己就可以做这个事情。

本文固定链接: http://www.dbdream.com.cn/2015/07/ora-14400-inserted-partition-key-does-not-map-to-any-partition%e9%94%99%e8%af%af/ | 信春哥,系统稳,闭眼上线不回滚!

该日志由 dbdream 于2015年07月30日发表在 Oracle, oracle 11g 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: ORA-14400 inserted partition key does not map to any partition错误 | 信春哥,系统稳,闭眼上线不回滚!
关键字: , ,

ORA-14400 inserted partition key does not map to any partition错误:等您坐沙发呢!

发表评论

快捷键:Ctrl+Enter