Buffer cache
的原理
http://s4/middle/8f5296d5hb0b820a43a93&690buffer cache的基本原理" TITLE="oracle buffer cache的基本原理" />
一、
1·)当一个服务器进程需要读数据到buffer cache中时,首先必须判断该数据在buffer
中是否存在,如果存在且可用,则获取该数据,根据lru算法在lru list上移动该block;如果buffer中不存在该数据,则需要从数据文件上获取
2)在读取数据之前,server进程需要扫描lru list
寻找free的buffer,扫描过程中server进程会把发现的所有已经被修改过的buffer移动到checkpoint queue上,这些dirty buffer随后可以被写出到数据文件。
3)如果checkpoint queue超过了阈值,server进程会通知dbwn去写出脏数据;这也是出发dbwr写的一个条件。
Select
kvittag,kvitval,kbvitdsc from
x$kvit
where
kvittag=’kcbldq’;
如果server进程扫描lru超过一个阈值仍然不能找到足够的free buffer
,将停止寻找,转而通知dbwn去写出脏数据,释放空间。
Select
kvittag,kvitval,kbvitdsc from
x$kvit
where
kvittag=’kcbfsp’;
同时由于增量检查点的引入,dbwn进程也会主动扫描lru list,将发现的dirty buffer
移动至checkpoint
queue,这个扫描也受到一个内部
约束,
Select
kvittag,kvitval,kbvitdsc from
x$kvit
where
kvittag=’kcbdsp’;
4)找到足够的buffer之后,server进程就可以将buffer从数据文件读入buffer cache
5)如果读取的block不满足读一致性要求,则server进程需要通过当前block版本和回滚段构造前镜像返回给用户。
从oracle
8i开始lru list
和dirty list
引入了辅助的list,用于提高管理效率,当数据库初始化时,buffer首先存放在lru的辅助list上,当被使用后移动到lru
的主list上,这样当用户进程搜索free buffer时,首先从辅助list上搜索,当dbwr搜索dirty buffer时
会首先从lru
的主list上进行搜索,提高了搜索效率和数据库性能。
二、转储buffer cache
的内容(1-10级)
Alter session set events
‘immediate
trace
name
buffers level 4’;
Level 1:仅包含buffer headers
的信息。
Level 2:包含buffer headers和buffer概要信息转储
Level
3:包含buffer headers和完整buffer内容转储。
三、cache
buffer lru
chain
闩锁竞争与解决
当用户进程需要读数据到buffer
cache时,或cache buffer根据lru算法进行管理时,就不可避免地要扫描lru list
获取可用buffer或更改buffer状态。在搜索的过程中必须获取latch,锁定lru的latch就是常见到的cache buffers lru chain
解决该latch竞争的方法:
1)适当的增加buffer cache,这样既可以减少读数据到buffer cache的机会,减少扫描lru list
的竞争
。
2)可以适当增加lru latch
的数量,修改_db_block_lru_latches
参数可以实现,
3)通过多缓冲池技术,可以减少不希望的数据老化和全表扫描等操作对于default池的冲击,从而减少竞争。
四、cache buffer chain
闩锁竞争与解决
1、在lru和checkpoint queue这两个内存结构之外,buffer cache的管理还存在另外两个重要的数据结构:hash bucket
和 cache buffer
chain
2、为了提高oracle
确定某个block在buffer中的位置,oracle引入了bucket的数据结构,oracle把管理的所有buffer通过一个内部的hash算法运算之后,存放到不同hash
bucket中,这样通过hash bucket进行分割之后,众多的buffer
被分布到一定数量的bucket之中,当用户需要在buffer中定位数据是否存在时,只需要通过同样的算法获得hash值,然后到相应的bucket中查找少量的buffer即可确定。每个buffer存放的bucket由buffer的数据块地址运算决定。
Bucket
内部,通过cache buffer
chain
(一个双向链表)将所有的buffer通过buffer header信息联系起来。
Buffer header
存放的是对应数据块的概要信息,包括数据文件号、块地址、状态等。要判断数据块在buffer中是否存在,通过检查buffer header即可确定。
3、bucket的数量受一个隐含参数的影响:
Db_block_hash_budkets
http://s8/middle/8f5296d5hb0b82533fb37&690buffer cache的基本原理" TITLE="oracle buffer cache的基本原理" />
1)
从oracle
8i开始,bucket的数量比以前大大增加,通过增加的bucket的稀释使得每个bucket上的buffer数量大大减少。
2)
oracle 8i之前,_db_block_hash_laches的数量和bucket的数量是一致的,每个latch管理一个bucket;从oracle 8i开始每个latch管理多个bucket,由于每个bucket上的buffer数量大大降低,所以latch的性能反而得到了提高。
3)
每个bucket存在一条cache buffer chain
4)
Buffer header
上存在指向具体buffer的指针。
5)
了解了以上算法后,可以想象,如果大量进程对相同的block进程进行操作,那么必然引发cache buffer chain的竞争,也就是通常所说的热快竞争。
五、x$bh和
buffer header
每个buffer在x$BH中都存在一条记录。
X$BH中有一个重要字段TCH
,TCH为touch的缩写,表示一个buffer的访问次数,buffer被访问的次数越多,说明该buffer越抢手,也就是可能存在热点块竞争的问题
查询当前数据库最繁忙的buffer
Select *
From (select addr,ts#,file#,dbarfil,dbablk,tch
From x$bh
Order by tch desc)
Where rownum<11;
结合dba_extents中的信息,可以查询到这些热点buffer都来自那些对象。
Select
e.owner,e.segmet_name,e.segment_type
From dba_extents e,
(Select *
From (select addr,ts#,file#,dbarfil,dbablk,tch
From x$bh
Order by tch desc)
Where rownum<11)
Where
e.relative_fno=b.dbarfl
And e.block_id<=b.dbablk
And e.block_id+e.blocks>dbablk;
如果需要确定热点块对象,可以从v$latch_children中查询具体的子latch信息。
X$BH中还存在另外一个关键字段hladdr
即hash chain latch
address,这个字段可以和v$latch_child.addr进行关联,这样就可以把具体的latch竞争和数据块关联起来。再结合dba_extents视图再结合v$sqlarea或者v$sqltext找到频繁操作这些对象的sql,然后对其进行优化,即可缓解或解决热点竞争的问题。
加载中,请稍候......