row cache lock
Oracle 将数据字典信息存于SGA内的行高速缓冲区(dictionary cache)行高速缓冲区位于共享池区域,可通过如下命令进行确认。
SQL> select pool,name,bytes from v$sgastat
2 where name='row cache';
POOL NAME BYTES
------------ -------------------------- ----------
shared pool row cache 7511248
想要修改数据字典内容的进程,应对其相应的row cache object获得row cache lock.其中最具代表性的是Sequence,
在获取Sequence的nextval过程中需要修改数据字典信息时,应该对row cache object以SSX(Shared Sub-Exclusive)模式获得row cache lock.
SSX模式之间因为不存在共享性,所以多个进程同时对相同Sequence调用nextval时,发生对于row cache lock的争用。若在获取row cache lock过程中会发生争用,
则等待row cache lock事件。row cache lock事件的P1=cache#,表示的不是对象信息,而是row cache 的类型。
row cache lock 不使用Enqueue结构,而通过row cache object信息内保存的锁拥有所有者列表和锁等待者列表,体现阻碍(blocking)机制。这些结构与
library cache lock,library cache pin,buffer lock相同。通常,将row cache lock称为row cache enqueue,这只是为了准确表达含义所使用的术语,但是与TX锁不同,
它不使用Enqueue结构。
许多进程同时使用没有赋予CACHE属性的Sequence时,可能大量发生row cache lock 等待事件。对没有使用CACHE的Sequence,如果调用nextval,则每次数据字典信息都应该被修改。
测试:创建 sequence
create sequence seq1
minvalue 1
maxvalue 99999999999999999999
start with 1
increment by 1
nocache;
SQL> declare var number;
begin
for i in 1 .. 100
loop
select seq1.nextval into var from dual;
dbms_output.put_line('var:'||var);
end loop;
end;
2 3 4 5 6 7 8 9
10 /
var:300160
var:300161
var:300162
var:300163
var:300164
var:300165
var:300166
var:300250
var:300251
var:300252
var:300253
var:300254
var:300255
var:300256
var:300257
var:300258
var:300259
PL/SQL procedure successfully completed.
begin
loop
execute immediate 'select seq1.nextval from dual';
end loop;
end;
select sid,event,p1,p1raw,p2,p3 from v$session where event='row cache lock';
p1 p1raw p2 p3
1 1616 row cache lock 13 000000000000000D 0 5
2 1617 row cache lock 13 000000000000000D 0 5
3 1619 row cache lock 13 000000000000000D 0 5
4 1620 row cache lock 13 000000000000000D 0 5
5 1624 row cache lock 13 000000000000000D 0 5
6 1626 row cache lock 13 000000000000000D 0 5
SQL> select CACHE# ,parameter from v$rowcache where cache#=13;
CACHE# PARAMETER
---------- --------------------------------
13 dc_sequences