在文档中,对INTERVAL分区执行一些操作之前都会先执行分区的锁定操作。
和其他类型的分区表不同,INTERVAL分区表的分区并不一定是已经存在的,分区是否存在与用户插入的数据的范围有关。
可以看到,文档在对INTERVAL分区执行SPLIT等分区操作之前都会执行一个锁分区的操作,事实上这个锁操作并非是避免用户DML对DDL操作的影响,而是为了确保要操作的分区存在:
SQL> CREATE TABLE T_PART_INTER
2 (ID NUMBER,
3 NAME VARCHAR2(30),
4 CREATE_DATE DATE)
5 PARTITION BY RANGE (ID)
6 INTERVAL (100)
7 (PARTITION P1 VALUES LESS THAN (100),
8 PARTITION P2 VALUES LESS THAN (200));
表已创建。
SQL> SELECT TABLE_NAME, PARTITION_NAME, HIGH_VALUE
2 FROM USER_TAB_PARTITIONS
3 WHERE TABLE_NAME = 'T_PART_INTER';
TABLE_NAME PARTITION_NAME HIGH_VALUE
--------------- --------------- ----------------------------------------
T_PART_INTER P1 100
T_PART_INTER P2 200
SQL> ALTER TABLE T_PART_INTER
2 MOVE PARTITION FOR(250);
ALTER TABLE T_PART_INTER
*
第1行出现错误:
ORA-02149:指定的分区不存在
SQL> LOCK TABLE T_PART_INTER
2 PARTITION FOR(250)
3 IN SHARE MODE;
表已锁定。
SQL> ALTER TABLE T_PART_INTER
2 MOVE PARTITION FOR(250);
表已更改。
SQL> SELECT TABLE_NAME, PARTITION_NAME, HIGH_VALUE
2 FROM USER_TAB_PARTITIONS
3 WHERE TABLE_NAME = 'T_PART_INTER';
TABLE_NAME PARTITION_NAME HIGH_VALUE
--------------- --------------- ----------------------------------------
T_PART_INTER P1 100
T_PART_INTER P2 200
T_PART_INTER SYS_P102 300
可以看到,LOCK TABLE使得Oracle新增了INTERVAL分区。
从这个现象推测,新增数据会导致INTERVAL新增分区,LOCK PARTITION也会导致新增分区,而新增数据会导致LOCK PARTITION,那么Oracle很可能是在监测到锁分区的操作之后对INTERVAL分区进行了新增操作。
SQL> LOCK TABLE T_PART_INTER
2 PARTITION FOR (320)
3 IN ROW SHARE MODE;
表已锁定。
SQL> LOCK TABLE T_PART_INTER
2 PARTITION FOR (430)
3 IN ROW EXCLUSIVE MODE;
表已锁定。
SQL> LOCK TABLE T_PART_INTER
2 PARTITION FOR (560)
3 IN SHARE ROW EXCLUSIVE MODE;
表已锁定。
SQL> LOCK TABLE T_PART_INTER
2 PARTITION FOR (670)
3 IN EXCLUSIVE MODE;
表已锁定。
SQL> LOCK TABLE T_PART_INTER
2 PARTITION FOR (780)
3 IN SHARE UPDATE MODE;
表已锁定。
SQL> SELECT TABLE_NAME, PARTITION_NAME, HIGH_VALUE
2 FROM USER_TAB_PARTITIONS
3 WHERE TABLE_NAME = 'T_PART_INTER';
TABLE_NAME PARTITION_NAME HIGH_VALUE
--------------- --------------- ----------------------------------------
T_PART_INTER P1 100
T_PART_INTER P2 200
T_PART_INTER SYS_P102 300
T_PART_INTER SYS_P103 400
T_PART_INTER SYS_P104 500
T_PART_INTER SYS_P105 600
T_PART_INTER SYS_P106 700
T_PART_INTER SYS_P107 800
已选择8行。
可以看到,由LOCK TABLE引发的任何模式的锁操作,都会导致INTERVAL分区的新增,但是,SELECT FOR UPDATE操作并不会引发这个操作:
SQL> SELECT *
2 FROM T_PART_INTER
3 PARTITION FOR(890)
4 FOR UPDATE;
未选定行
SQL> SELECT TABLE_NAME, PARTITION_NAME, HIGH_VALUE
2 FROM USER_TAB_PARTITIONS
3 WHERE TABLE_NAME = 'T_PART_INTER';
TABLE_NAME PARTITION_NAME HIGH_VALUE
--------------- --------------- ----------------------------------------
T_PART_INTER P1 100
T_PART_INTER P2 200
T_PART_INTER SYS_P102 300
T_PART_INTER SYS_P103 400
T_PART_INTER SYS_P104 500
T_PART_INTER SYS_P105 600
T_PART_INTER SYS_P106 700
T_PART_INTER SYS_P107 800
已选择8行。
oracle视频教程请关注: