在文档中,对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视频教程请关注: