这篇文章 是我给team做内部培训用的,现在拿出来share一下
Buffer Cache 原理
我们在监控等待事件,查看AWR,ASH报表的时候经常会看到latch: cache buffers chains,有可能还会看到latch: cache buffers lru chain这些等待事件,对于cache buffers chains这个等待事件,相信是大家最为头疼的,如果对Buffer Cache理解不深,那么你就遇到这些等待事件就会束手无策。本文的目的就是通过讲解Buffer Cache原理,使大家得心应手的处理这些latch争用。
Buffer Cache概述
Buffer Cache是SGA的一部分,Oracle利用Buffer Cache来管理data block,Buffer Cache的最终目的就是尽可能的减少磁盘I/O。Buffer Cache中主要有3大结构用来管理Buffer Cache。
Hash Bucket & Hash Chain List :Hash Bucket与Hash Chain List用来实现data block的快速定位。
LRU List :挂载有指向具体的free buffer, pinned buffer以及还没有被移动到 write list的dirty buffer 等信息。所谓的free buffer就是指没有包含任何数据的buffer,所谓的pinned buffer,就是指当前正在被访问的buffer。
Write(Dirty)List :挂载有指向具体的 dirty block的信息。所谓的dirty block,就是指在 buffer cache中被修改过但是还没有被写入到磁盘的block。
Hash Bucket与Hash Chain List
Oracle将buffer cache中所有的buffer通过一个内部的Hash算法运算之后,将这些buffer放到不同的 Hash Bucket中。每一个Hash Bucket中都有一个
Hash Chain List,通过这个list,将这个Bucket中的block串联起来。
下面举个简单的例子来介绍一下Hash 算法,Oracle的Hash 算法肯定没这么简单,具体算法只有Oracle公司知道。
• 一个简单的mod函数 ,我们去mod 4
Ø 1 mod 4 = 1
Ø 2 mod 4 = 2
Ø 3 mod 4 = 3
Ø 4 mod 4 = 0
Ø 5 mod 4 = 1
Ø 6 mod 4 = 2
Ø 7 mod 4 = 3
Ø 8 mod 4 = 0
……………省略…………………..
那么这里就相当于创建了4个Hash Bucket
如果有如下block:
blcok :DBA(1,1) ------> (1+1) mod 4 =2
block :DBA(1,2) ------> (1+2) mod 4 =3
block :DBA(1,3) ------> (1+3) mod 4 =0
block :DBA(1,4) ------> (1+4) mod 4 =1
block :DBA(1,5) ------> (1+5) mod 5 =2
………........省略…………………....
比如我要访问block(1,5),那么我对它进行Hash运算,然后到Hash Bucket为2的这个Bucket里面去寻找,Hash Bucket 为2的这个Bucket 现在有2个block,
这2个block是挂在Hash Chain List上面的
Hash Chain List到底是怎么组成的呢?这里我们就要提到x$bh这个基表了
SQL> desc x$bh
Name Null? Type
----------------------- - ----------------
ADDR RAW(8) ---block在buffer cache中的address
INDX NUMBER
INST_ID NUMBER
HLADDR RAW(8) --latch:cache buffers chains 的address
BLSIZ NUMBER
NXT_HASH RAW(8) ---指向同一个Hash Chain List的下一个block
PRV_HASH RAW(8) ---指向同一个Hash Chain List的上一个block
NXT_REPL RAW(8)---指向LRU list中的下一个block
PRV_REPL RAW(8)---指向LRU list中的上一个block
………………省略…………………………
Hash Chain List就是由x$bh中的NXT_HASH,PRV_HASH 这2个指针构成了一个双向链表,其示意图如下:
通过NXT_HASH,PRV_HASH这2个指针,那么在同一个Hash Chain List的block就串联起来了。
理解了Hash Bucket 和 Hash Chain List,我们现在来看看
Hash Bucket 与 Hash Chain List管理Buffer Cache 的结构示意图
从图中我们可以看到,一个latch:cache buffers chains(x$bh.hladdr) 可以保护多个Hash Bucket,也就是说,如果我要访问某个block,我首先要获得这个latch,一个Hash Bucket对应一个Hash Chain List,而这个
Hash Chain List挂载了一个或者多个Buffer Header。
Hash Bucket的数量受隐含参数_db_block_hash_buckets的影响,
Latch:cache buffers chains的数量受隐含参数_db_block_hash_latches的影响
该隐含参数可以通过如下查询查看:
SQL> select * from v$version;
BANNER
------------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi