应该说cache buffer chain latch可以以只读模式有条件的共享:单独从查询来说,不会产生任何的lock,enqueue,对chain的结构也不会破坏,所以说可以共享。但是数据库会默认3秒钟记录一下buffer的访问情况,即更新tch,而这个信息记录在buffer header上,而chain又是由buffer header串起来的,所以更新时,需要有latch,最后是我的验证。
参考:http://space.itpub.net/?uid-22034023-action-viewspace-itemid-682438
当多个进程请求同一类别的同一个latch时,是需要发生等待的,同一类别的同一latch是互斥的,即都是x模式的。只有cache buffer chain latch比较特殊,ORACLE宣称,9I以后这种latch如果只是只读操作,可以被共享。
可是我们实验发现(实验放在最后面,有需要的看下),只读也会产生cache buffer chain latch。这是怎么回事呢?
我们知道cache buffer chain latch保护的是cache buffer chain,这个cache buffer chain上串了同一hash值的buffer header。
当我们需要读取一个数据块的时候,ORACLE首先需要获得cache buffer chain latch,然后在cache buffer chain上找header,找到header后,需要获得 buffer lock,然后就可以读数据块了。大概就是这么一个过程。
既然只读是可以共享的,那为什么还能产生cache buffer chain latch。
问题就出在了找到header后,进程访问buffer的时候,需要修改header的信息。这个时候需要以x模式获得cache buffer chain latch。因此导致了如果有其他进程有读取请求,也会产生cache buffer chain latch等待。
修改的是header的什么信息呢?
首先看下header上都有哪些信息。
BH (0xa5f72538) file#:9 rdba: 0x02400e81 (9/3713) class: 1 ba: 0xa514c000
set: 10 bsz: 8192 bsi: 0 sflg: 0 pwc: 0, 25 lid: 0x00000000,0x00000000
dbwrid: 0 obj: 12224 objn: 12224 tsn: 5 afn: 9
hash: [0x9ecd8740,0x9ecd8740] lru: [0xa9070438,0xa5fa1c98]
ckptq: [NULL] fileq: [NULL] objq: [0x681f5218,0x681f5218]
use: [0xb30892b8,0xb30892b8] wait: [NULL]
st: XCURRENT md: SHR tch: 3
flags:
LRBA: [0x0.0.0] LSCN: [0x0.0] HSCN: [0xffff.ffffffff] HSUB: [65535]
cr pin refcnt: 0 sh pin refcnt: 0
重点关注一下use: [0xb30892b8,0xb30892b8] wait: [NULL]
st: XCURRENT md: SHR tch: 3,use是当前使用者列表,wait是当前等待着列表,MD是mode的意思,可以取的值有excl,代表独占模式,如dml操作。SHR代表shared模式,如select操作。TCH是touch的意思,是lru算法的核心内容。
当获取buffer lock的时候,需要短暂的以x模式获得cache buffer chain latch,去修改buffer header上的一些metadata信息。同样的,释放buffer lock的瞬间,也需要以x模式,短暂的获得cache buffer chain latch。
以下主要测试tch:
SQL> create table testchn as select * from dba_objects where rownum <100;
Table created.
SQL> create unique index idx_object_id on testchn(object_id);
Index created.
SQL> select f,b from (
2 select dbms_rowid.rowid_relative_fno(rowid) f,
3 dbms_rowid.rowid_block_number(rowid) b
4 from testchn) group by f,b order by b;
F B
---------- ----------
1 52514
1 52515
SQL> select file#,dbablk,tch from x$bh where bj=
2 (select data_object_id from dba_objects
3 where wner='SYS' and object_name='TESTCHN')
4 order by dbablk;
FILE# DBABLK TCH
---------- ---------- ----------
1 52513 4
1 52514 2
1 52515 2
--清空buffer
SQL> alter system flush buffer_cache;
System altered.
SQL> select file#,dbablk,tch from x$bh where bj=
(select data_object_id from dba_objects
2 3 where wner='SYS' and object_name='TESTCHN')
order by dbablk; 4
FILE# DBABLK TCH
---------- ---------- ----------
1 52513 0
1 52514 0
1 52515 0
SQL> select file#,block#,status from v$bh where bjd=
2 (select data_object_id from dba_objects
3 where wner='SYS' and object_name='TESTCHN')
4 order by block#;
FILE# BLOCK# STATUS
---------- ---------- -------
1 52513 free
1 52514 free
1 52515 free
SQL> select file#,dbablk,tch from x$bh where bj=
2 (select data_object_id from dba_objects
3 where wner='SYS' and object_name='TESTCHN')
4 order by dbablk;
FILE# DBABLK TCH
---------- ---------- ----------
1 52513 0
1 52514 0
1 52515 0
--只读查询,
SQL> select * from testchn where object_id=44;
OWNER
------------------------------
OBJECT_NAME
--------------------------------------------------------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- -------------------
CREATED LAST_DDL_ TIMESTAMP STATUS T G S
--------- --------- ------------------- ------- - - -
SYS
I_USER1
44 44 INDEX
22-AUG-10 22-AUG-10 2010-08-22:20:45:20 VALID N N N
SQL> /
OWNER
------------------------------
OBJECT_NAME
--------------------------------------------------------------------------------
SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- -------------------
CREATED LAST_DDL_ TIMESTAMP STATUS T G S
--------- --------- ------------------- ------- - - -
SYS
I_USER1
44 44 INDEX
22-AUG-10 22-AUG-10 2010-08-22:20:45:20 VALID N N N
--block 52514 的TCH 增加了两次
SQL> select file#,dbablk,tch from x$bh where bj=
2 (select data_object_id from dba_objects
3 where wner='SYS' and object_name='TESTCHN')
4 order by dbablk;
FILE# DBABLK TCH
---------- ---------- ----------
1 52513 0
1 52514 2
1 52514 0
1 52515 0
--可通过dump buffer header来验证tch:
alter session set events 'immediate trace name buffers level 1';
BH (0x23ff9fbc) file#: 1 rdba: 0x0040cd22 (1/52514) class: 1 ba: 0x23fa2000
set: 3 blksize: 8192 bsi: 0 set-flg: 2 pwbcnt: 0
dbwrid: 0 obj: 46133 objn: 46133 tsn: 0 afn: 1
hash: [243eb96c,290c5e88] lru: [26018f80,26018a00]
ckptq: [NULL] fileq: [NULL] objq: [27bbdc18,27bbdc18]
st: XCURRENT md: NULL tch: 2
flags:
LRBA: [0x0.0.0] HSCN: [0xffff.ffffffff] HSUB: [65535]
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/758322/viewspace-700616/ ,如需转载,请注明出处,否则将追究法律责任。