ORACLE为了提高buffer cache性能(大内存),使用了多个working set
每个working set都由一个名为“Latch:cache buffers lru chain”的latch来保护,每一个lru latch对应一个working set。
而每个被加载到buffer cache的buffer header都以轮询的方式挂到working set上去。
而每个被加载到buffer cache的buffer header都以轮询的方式挂到working set上去。也就是说,当buffer cache加载一个新的数据块时,其对应的buffer header会去找一个可用的lru latch,如果没有找到,则再找下一个lru latch,直到找到为止。如果轮询完所有的lru latch也没能找到可用的lru latch,该进程只有等待latch free等待事件,同时出现在v$session_wait中,并增加“latch misses”。
如果启用了多个DBWR后台进程的话,每个DBWR进程都会对应一个不同的working set,而且每个DBWR只会处理分配给它的working set,不会处理其他的working set。
P_NAME P_DESCRIPTION P_VALUE ISDEFAULT ISMODIFIED ISADJ
---------------------------------------- -------------------------------------------------- ------------------------------ --------- ---------- -----
_db_block_lru_latches number of lru latches 8 TRUE FALSE FALSE
SYS@ bys3>select name from v$latch_children where name like '%buffers lru%';
NAME
----------------------------------------------------------------
cache buffers lru chain
cache buffers lru chain
cache buffers lru chain
cache buffers lru chain
cache buffers lru chain
cache buffers lru chain
cache buffers lru chain
cache buffers lru chain
cache buffers lru chain
cache buffers lru chain
cache buffers lru chain
cache buffers lru chain
cache buffers lru chain
cache buffers lru chain
cache buffers lru chain
16 rows selected.
SYS@ bys3>select d.blk_size,c.child#,p.bp_name,c.gets,c.sleeps from x$kcbwds d,v$latch_children c,x$kcbwbpd p where d.set_latch=c.addr and d.set_id between p.bp_lo_sid and p.bp_hi_sid order by c.child#;
BLK_SIZE CHILD# BP_NAME GETS SLEEPS
---------- ---------- -------------------- ---------- ----------
8192 1 KEEP 18 0
8192 3 RECYCLE 18 0
8192 5 DEFAULT 8887 5
2048 7 DEFAULT 18 0
4096 9 DEFAULT 18 0
8192 11 DEFAULT 18 0
16384 13 DEFAULT 18 0
32768 15 DEFAULT 18 0
8 rows selected.
每个working set中,还有其它的队列:ckpt queue,ObjectQ、FileQ等,根据块的不同,也可能会同时挂载在这些队列下。
working set与lru latch一一对应。lru latch的数量是由一个隐藏参数:_db_block_lru_latches决定的。
该参数缺省值为DBWR进程的数量×8。该参数最小必须为8,如果强行设置比8小的数值,oracle将忽略你设置的值,而使用8作为该参数值。
###############################################
6.最后结合上图:用一段话来简洁的概括buffer cache的内存结构:
buffer cache中有pool,每个pool中至少有8个Latch:cache buffers lru chain,每个Latch:cache buffers lru chain对应着一个working set,每个working set中,有多个CBC LATCH来,每个CBC LATCH管理着多个hash bucket,每个hash bucket对应着一条hash chain。
数据块在读入buffer cache中时,同时会在buffer cache中构造一个buffer header,ORACLE对数据块的DBA进行hash运算,根据运算结果将buffer header挂载到相应的hash chain上。
同时,每个working set中,有一对LRU和LRUW链表,buffer cache中的数据块,胜块会挂载到LRUW链表,其它块在LRU链表。也就是buffer cache中的数据块,肯定在LRU和LRUW链表之一:不能同时存在这两个链表上。