ITPub博客

首页 > 数据库 > Oracle > latch与等待(2)--cache buffer yl

latch与等待(2)--cache buffer yl

Oracle 作者:liuxiaohua8282 时间:2014-02-25 16:43:39 0 删除 编辑

每个working set都具有它自己的一组LRULRUW链表(LRULRUW链表总是成对出现的)。
ORACLE
为了提高buffer cache性能(大内存),使用了多个working set
每个working set都由一个名为“Latch:cache buffers lru chain”latch来保护,每一个lru latch对应一个working set
而每个被加载到buffer cachebuffer 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

SYS@ prod>select name from v$latch_children where name like '%buffers lru%' and gets != 0;

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

8 rows selected

 

SYS@ prod>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                         14          0

      8192          3 RECYCLE                      14          0

      8192          5 DEFAULT                   29310          0

      2048          7 DEFAULT                      14          0

      4096          9 DEFAULT                      14          0

      8192         11 DEFAULT                      14          0

     16384         13 DEFAULT                      14          0

     32768         15 DEFAULT                      14          0

8 rows selected.

总结:buffer cache中有pool,每个pool中至少有8Latch: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中,有一对LRULRUW链表,buffer cache中的数据块,胜块会挂载到LRUW链表,其它块在LRU链表。也就是buffer cache中的数据块,肯定在LRULRUW链表之一:不能同时存在这两个链表上。

 

2.6:现在再回过头,看看怎样查找BUFFER CACHE看看数据是否已经存在? 

(Y)  如果数据在BUFFER CACHE中存在的情况。 

1 根据要查找的数据块的DBA等信息,通过上面给的HASH算法( Hash Bucket MOD(Data 

Block Address, _DB_BLOCK_HASH_BUCKETS) ),得到该数据块所在的Hash Bucket 

2)定位到对应的Hash Bucket上,在该Hash Bucket对应的Cache Buffers Chain中加上Cache Buffers Chains Latch,然后从Cache Buffers Chain对应的第一个Buffer Header开始扫描查找,直至之后一个。在这个扫描查找过程中,为防止对Cache Buffers Chain并发访问,将一直持有Cache Buffers Chains Latch Cache Buffers Chain上查找的具体逻辑如下: 

1.比较Buffer Header上所记录的Block地址,不符合条件跳过此Buffer Header

 2.跳过statuscrBuffer Header 

3.如果Buffer Header状态为reading则等待,直到状态改变后比较Buffer Header 记录的Block地址是否符合 

4.若发现Block地址符合的Buffer Header,查该Buffer Header是否位于正在使用的list上,如果是,则判断已存在的lock mode,与要求的lock mode是否兼容,如果兼容则返回该Buffer Header中记录的Buffer地址,将当前process id放入Buffer Header 所处的正在使用的list 

5.如果lock mode不兼容,用Buffer Header所指向的Buffer中的内容构建一个xcurrentBuffer 和一个cr状态的Buffer Header(指向新建立xcurrent状态的复制Buffer

6.搜索完整个Hash Chain还未发现需要的Buffer Header,从disk读取datafile,读入到Buffer Cache 相应的Buffer Header 挂在Hash Chain 附: 

 

Buffer Header指向Buffer6种状态:  

(可以参照v$bhSTATUS) 

1.free =可以被重用的block 

2.xcurrent=EXCLUSIVE方式获取的当前模式的block(insert,update,delete时产生),scurrent=可以与其他instance共享的当前模式block 

3.cr=一致读块,永远不会写入disk 

4.reading=正从disk读取出来的块

5.mreciver=正在进行介质恢复的block 

6.ircovery=正在进行instance recoveryblock

3 获得第2)步中查到的可以直接访问的Buffer Header或者构造一致性读后的Buffer 

Header中的Buffer地址到Buffer Memory来获得数据。  

 

2.7

如果上面在Hash Chain中查找不到对应的Buffer Header的情况下,也就前面的问题的第二种情况: 

(N) 如果数据在BUFFER CACHE中不存在,则需要从数据文件中读取数据块到BUFFER CACHE中去。这个时候,需要查找在BUFFER CACHE中寻找足够的内存空间来读取相关的数据。 

再看看前面给的BUFFER CACHE示例图: 可以看到2条链(LRULRUW),这2条分别将Buffer Header连接起来,和Cache Buffers Chain类似。下面看看这2条链的作用: 

1)  LRU表示Least Recently Used,也就是指最近最少使用的Buffer Header链表。LRU链表串连起来的Buffer Header都指向可用数据块(Free Buffer)。

2)   LRUW则表示Least Recently Used Write,也叫做Dirty List,也就是脏数据块链表,LRUW串起来的都是修改过但是还没有写入数据文件的内存数据块所对应的Buffer HeaderDirty Buffer)。

3)  一个数据块要么在lru要么lruw,不能同时存在

 

 

所以,当前面查找数据在BUFFER CACHE中不存在的时候(即在Hash Chain中查找不到对应的Buffer Header的情况下)就要扫描LRU List寻找FreeBuffer,在扫描过程将持有Cache Buffers Lru Chain Latch(其Latch数量由隐含参数_db_block_lru_latches决定)。扫描过程中会把已经被修改过的Buffer移动到LRUW列表上

总的在BUFFER CACHE中查找数据,可以简单的表示为下图

 

latch与等待(2)--cache <wbr>buffer

通常有2中情况或导致Latch出现竞争: 

1)  某一进程长时间的持有Latch,导致其他进程不能正常的得到Latch,只能等待。

2)  可能存在大量的Latch请求。

 

如果出现Cache Buffers Chains Latch竞用严重,根据前面的原理,那么可能有如下原因: 

1 当多个会话重复访问一个或多个由同一个子Cache Buffers Chains Latch保护的块时热点

块(可以关注X$BH中的TCH字段)。 

2 大量并发执行的低效SQL。低效的SQL通常需要获取大量的逻辑读,而得到一次逻辑IO就得获得一次Cache Buffers Chains Latch 

3 Hash Bucket中存在长的Cache Buffers Chains,导致查询数据时候,长时间持有Latch 

 

如果出现Cache Buffers Lru Chain Latch竞用严重,那么可能有如下原因:

 1 可能BUFFER CACHE分配的空间不够,导致读数据到BUFFER CACHE的时候,不断的扫描LRU List 

<!-- 正文结束 -->

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/21598700/viewspace-1115147/,如需转载,请注明出处,否则将追究法律责任。

上一篇: 没有了~
下一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2009-05-08