12c 混合列压缩行级锁

12c 混合列压缩行级锁

我们知道,在11g时,混合列压缩(HCC)的表上进行DML时,是会锁住整个压缩单元的(CU,compression unit),这样就降低了并发性。

Oracle在12cR1推出了混合列压缩的行级锁机制,在12cR1之后,在定义使用HCC的表时,可以指定在做DML时,使用行级锁,缺省还是锁整个CU。

 

实验:

首先测试没有行级锁的情况:

SQL> create table test1(col1,col2) compress for query high as select rownum,rownum*10 from dual connect by rownum <= 100;

因为我们知道一个CU一般在32K到256K之间,所以这样的数据量应该在一个CU里面。

 

在一个会话种,执行:

SQL> update test1 set col2=col2+1 where col1=100;

已更新 1 行。

SQL> select * from v$mystat where rownum < 2;

SID STATISTIC#      VALUE     CON_ID
———- ———- ———- ———-
761          0          0         41

SQL>

 

我们现在知道这个会话的ID是761

 

在另一个会话中,我们尝试更新另一条记录:

SQL> select * from v$mystat where rownum < 2;

SID STATISTIC#      VALUE     CON_ID
———- ———- ———- ———-
638          0          0         41

SQL> update test1 set col2=col2+1 where col1=99;

 

会话hang住,等待取得锁

查看V$LOCK视图:

 

SQL> select * from v$lock where con_id = 41;

ADDR             KADDR                   SID TYPE        ID1        ID2
—————- —————- ———- —- ———- ———-
LMODE    REQUEST      CTIME      BLOCK     CON_ID
———- ———- ———- ———- ———-
00007F0DFB06F2C0 00007F0DFB06F330        638 TM        70854          0
3          0        138          2         41

00007F0DFB06F2C0 00007F0DFB06F330        761 TM        70854          0
3          0        199          2         41

0000000CA1B5D258 0000000CA1B5D2D8       638 TX       196639        985
0          6        138          0         41
ADDR             KADDR                   SID TYPE        ID1        ID2
—————- —————- ———- —- ———- ———-
LMODE    REQUEST      CTIME      BLOCK     CON_ID
———- ———- ———- ———- ———-
0000000C30BECFB8 0000000C30BED040        761 TX       196639        985
6          0        199          1         41

0000000CA1B38E08 0000000CA1B38E88        506 TS            3          1
3          0    2269603          2         41

 

从视图中很容易看到,761会话持有独占TX锁(6),而638请求TX独占锁(6),所以证明普通模式HCC表更新时,是锁整个CU的。

 

如果使用下面的语句创建表,就启用了ROW LEVEL LOCKING

SQL> create table test1(col1,col2) compress for query high row level locking as select rownum,rownum*10 from dual connect by rownum <= 100;

 

我们还是像上个实验中做的一样,在两个会话中分别更新不同的记录,就都能更新成功,没有锁等待了。

查询V$LOCK查看锁情况:

SQL> select * from v$lock where con_id = 41;

ADDR             KADDR                   SID TYPE        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK     CON_ID
—————- —————- ———- —- ———- ———- ———- ———- ———- ———- ———-
0000000C30BEDB90 0000000C30BEDC18        761 TX       131075        962          6          0         17          2         41
0000000C308B1EE8 0000000C308B1F70        638 TX       393224        522          6          0          6          2         41
00007F0DFB0702F8 00007F0DFB070368        638 TM        70856          0          3          0          6          2         41
00007F0DFB0702F8 00007F0DFB070368        761 TM        70856          0          3          0         17          2         41
0000000CA1B38E08 0000000CA1B38E88        506 TS            3          1          3          0    2270761          2         41

可以看到,761和638两个会话都持有TX独占锁(6)。

 

当然,我们知道更新后就会解压缩记录,这样的功能实际价值不大,但是我们能看到,Oracle的HCC在一点一点地增强,希望最后HCC表能够像普通表一样操作。

Comments are closed.