暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle分区表上drop partition引起查询报ORA-08103

DBA智慧库 2021-04-21
3424

业务侧说有报“ORA-08103: object no longer exists”的错误,但是查看后对应的表存在,比较巧的是这个表是分区表,所以推测是在此期间对分区表的DDL(drop partition)导致的问题。

1、测试数据的准备

create table t_list_partition(a int,b int)

partition by list(a)

(partition p1 values (1),

partition p2 values (2)

);

SQL> declare

2    -- Local variables here

3    i integer;

4  begin

5    i:=200001;

6  WHILE i <= 1000000

7  LOOP

8       insert into t_list_partition (a,b) VALUES(1,i);

9   i := i+1;

10  END LOOP;

11   if mod(i,20000)=0 then

12      commit;

13      end if;

14      commit;

15  end;

16  /

PL/SQL procedure successfully completed

SQL>

SQL> declare

2    -- Local variables here

3    i integer;

4  begin

5    i:=0;

6  WHILE i <= 1000000

7  LOOP

8       insert into t_list_partition (a,b) VALUES(1,i);

9   i := i+1;

10  END LOOP;

11   if mod(i,20000)=0 then

12      commit;

13      end if;

14      commit;

15  end;

16  /

PL/SQL procedure successfully completed

SQL>

SQL> declare

2    -- Local variables here

3    i integer;

4  begin

5    i:=0;

6  WHILE i <= 10000000

7  LOOP

8       insert into t_list_partition (a,b) VALUES(2,i);

9   i := i+1;

10  END LOOP;

11   if mod(i,20000)=0 then

12      commit;

13      end if;

14      commit;

15  end;

16  /

PL/SQL procedure successfully completed

SQL> insert into t_list_partition select * from t_list_partition;

22000004 rows inserted

SQL> commit;

Commit complete

SQL>

SQL> insert into t_list_partition select * from t_list_partition;

44000008 rows inserted

SQL> commit;

Commit complete

2、测试:

2.1场景1:

session1中操作的数据包含t_list_partition P1和 P2中的数据,drop p2,session中的SQL报错

session1:

操作的数据包含t_list_partition P1和 P2中的数据

SQL> insert into t_csp select * from t_list_partition where (b>9000000 and b<9000000) or (b>900000 and b<8000000);

insert into t_csp select * from t_list_partition where (b>9000000 and b<9000000) or (b>900000 and b<8000000)

session 2中:在session1执行后还未执行完之前,在session中2执行

SQL> alter table t_list_partition drop partition P2;

Table altered

session1:session2执行后,session1中报错

这时session1中的sql报错:

ORA-08103: object no longer exists

2.2场景2:

session1中要读取的数据只包含P1,不包含P2,但是分区字段限制在P1分区,drop partition P2对session1无影响

session1:

SQL> insert into t_csp select * from t_list_partition where a=1 and ((b>9 and b<=300000) or (b>500000 and b<1000000));

38399520 rows inserted

SQL> commit;

Commit complete

SQL>

session2:

SQL> alter table t_list_partition drop partition P2;

Table altered

2.3场景3:

session1中sql语句只涉及P2分区的数据,但是不带分区字段的限制,drop partition P2对session1报错

重新组织数据:

SQL> select max(b) from t_list_partition where a=2;

MAX(B)

----------

100000000

SQL> select max(b) from t_list_partition where a=1;

MAX(B)

----------

1000000

session1:sql语句只涉及P2分区的数据,但是不带分区字段的限制

SQL> insert into t_csp select * from t_list_partition where (b>1100000 and b<9990000) or (b>11100000 and b<799990000);

session2 :在session1执行后还未执行完之前,在session中2执行

SQL> alter table t_list_partition drop partition P2;

Table altered

session1:报错

insert into t_csp select * from t_list_partition where (b>1100000 and b<9990000) or (b>11100000 and b<799990000)

ORA-08103: object no longer exists

2.4场景4:

session1中sql语句的b值只包含P1分区的数据,不包含p2分区的数据,但是不带分区字段的限制,drop partition P2对session1报错

P1中的b指是从0到1000000,p2分区中的b值都是大于1000000

SQL> select count(*) from t_list_partition3 where a=2 and b<1000000;

COUNT(*)

----------

0

session1:操作中的b值只包含P1分区的数据,不包含p2分区的数据

SQL> insert into t_csp select * from t_list_partition4 where (b>5 and b<200000) or (b>300000 and b<980000);

session2:session1的sql执行后,在session2中执行如下sql

SQL> alter table t_list_partition4 drop partition P2;

Table altered

session1:报错

insert into t_csp select * from t_list_partition4 where (b>5 and b<200000) or (b>300000 and b<980000)

ORA-08103: object no longer exists

综上所述,如果分区字段上有需要drop分区的操作(比如定时的把历史数据迁移走后,删除对应的分区),最好是此分区表上所有的SQL语句都要带上分区字段的限制(避免查询在这期间要drop的分区),在业务进行期间且不要删除业务需要用的分区。


最后修改时间:2021-04-21 15:02:20
文章转载自DBA智慧库,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论