全部博文(389)
分类: Oracle
2011-08-26 22:05:17
CACHE BUFFER CHAIN
和所有的计算机部件设计思想一样,ORACLE也使用内存作为CACHE机制, 这样避免每次读取都需要从磁盘读取,直接就可以在内存中读取以前读取过的数据,从而提升了效率.同时对块的修改也是内存中完成的,由后台进程DBWR根据各种规则统一写到磁盘中.
为了高效地的管理CACHE(本文主要关注BUFFER CACHE),ORACLE引入了几种数据数据结构.LRU LIST用来管理如何更新CACHE中的块,LRUW用来存放已修改过的,但是还没有写到磁盘上块(也称为脏块),CHECKPOINT 队列,用来存放在在发生CHECKPOINT时必须写回到磁盘上的块,
关于如何定位一个数据,ORACLE使用了BUFFER CHAIN,由多个BUFFER通过某种算法来形成一个条BUFFER CHAIN,多条BUFFER CHAIN HEADER被链接在一个称为CACHE BUFFERS LRU CHAIN.
当ORACLE需要查找一个块是否在内存中时,根据这个块的RBA的地址进行HASH计算,然后得出是在哪一个CACHE BUFFERS LRU CHAIN.如果是准备是修改操作还需要请求
CACHE BUFFER LRU CHAIN LATCH来进行保护,再过在这个一条CACHE BUFFERS LRU CHAIN进行HASH计算,得出在哪一个BUFFER CHAIN,然后请求这一条BUFFER CHAIN的CACHE BUFFER CHAIN LATCH再进行相关操作.同时更新相关的LRU的数据结构,把这个块的地址放到LRU的热端.
在ORACLE 8I以前由于整个系统中只有一个CACHE BUFFERS LRU CHAIN..所以在高并发修改操作的系统中,可能CACHE BUFFERS LRU CHAIN争用很严重,后来通过引入多个LRU CHAIN结构来解决这个问题;如:
NAME CHILD# GETS MISSES
------------------------------ ---------- ---------- ----------
cache buffers lru chain 16 0 0
cache buffers lru chain 15 10 0
cache buffers lru chain 14 0 0
cache buffers lru chain 13 10 0
cache buffers lru chain 12 0 0
cache buffers lru chain 11 10 0
cache buffers lru chain 10 0 0
cache buffers lru chain 9 10 0
cache buffers lru chain 8 0 0
cache buffers lru chain 7 10 0
cache buffers lru chain 6 0 0
NAME CHILD# GETS MISSES
------------------------------ ---------- ---------- ----------
cache buffers lru chain 5 11628 3
cache buffers lru chain 4 0 0
cache buffers lru chain 3 10 0
cache buffers lru chain 2 0 0
cache buffers lru chain 1 10 0
可以通过参数_DB_BLOCK_LRU_LATCHES*2, 来修改CACHE BUFFERS LRU CHAIN的个数.比如想要修改为32个,那么就设置这个参数为16.,在ORACLE 11G中默认为CPUS*16,一般不建议修改.在CACHE BUFFERS LRU CHAIN小于99%的情况一下就认会争用很严重了,首先从应用修改,是否有大量并发的更新操作,或是修改PCTFREE等.
一条CACHE BUFFERS LRU CHAIN上有多个少BUFFER CHAIN由参数_DB_BLOCK_HASH_BUCKETS参数来决定的.通过以下查询显示:
SQL> select name,count(child#)
2 from v$latch_children
3 where name='cache buffers chains'
4 group by name;
NAME COUNT(CHILD#)
------------------------------ -------------
cache buffers chains 2048
2048/16=128表示在每个CACHE BUFFER LRU CHAIN上都有128个CACHE BUFFER CHAIN.而在我的实验中的环境中共用
number of buffers
kcbnbh 30752
在每一条的BUFFER CACHE CHAIN上有15个BUFFER.具体可能根据SGA和ORACLE的版本不同而不同.
在一些热块很严重的系统中会产生cache buffers chains争用.如要进行相应的操作
一般还是从应用入手,实在不得已的情况下才考虑使用_DB_BLOCK_HASH_BUCKETS来对块进行分散.