在文档中,对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视频教程请关注:http://u.youku.com/user_video/id_UMzAzMjkxMjE2.html