浅析Buffer Cache

来源:互联网 发布:setscale java 编辑:程序博客网 时间:2024/06/03 10:51
Buffer Cache
作用:用来缓存data files中的数据
结构:如下图所示

包含不同大小的block(是Oracle I/O的最小单位),块中包含的数据与数据文件中的物理数据是一一对应的。各个数据块之间通过不同的链来连接,可以存在多种链类型,不同的链类型代表不同的意义

链种类:
CBC:挂载数据块头部的信息,数据快头部包含我们的数据地址和模式对象等信息,而CBC链正是利用这个头部信息中的地址信息来指向buffer cache中缓存块,来获取需要的数据。
内部结构:类似前面share pool中的链结构


工作原理:
首先我们的server process在根据客户端的SQL解析成功后,根据需要获取的数据,数据库进行内部计算得到一个结果,这个结果就是我们对应的链编号和块信息,在对应的列找到了这个块地址信息后,就去对应的buffer中查找这个数据是在这个buffer,没有就会去磁盘中找到这个数据,先写到buffer中,在将数据返回给用户,即产生一次物理I/O;反正存在就直接返回给用户。

LRU(Lest Rest Use 最近最少使用):串联buffer中的干净块
内部结构:链分成冷、热两端

工作原理:
根据LRU算法,将buffer中的干净块全部串起来,但是在串的时候还是会有一定的规律,将最近最少(例如最近被修改了1次)为被使用的块串在冷端,在最近最多(最近被修改了3次)这种块串在热端,这样就有利于我们在需要buffer中的内存是,优先去覆盖冷端的数据,这样可以减少发生物理I/O的次数。

LRW(Lest Rest Writer最近最少写):串联buffer中的脏块,将最近频繁修改的块串在热端,其他的块串在冷端

工作原理:
根据最近最少未写入的算法,将buffer中的脏块相互串联起来,将最近由DBWR频繁写的数据块串在热端,反之串在冷端;这样有利于DBWR在将赃块写入磁盘时优先写入冷端的数据,后面需要使用到干净块时,也就优先使用这些冷端块,这样可以减少物理I/O的产生。

查询当前脏块:
select cpdrt,cplrba_seq||'.'||cplrba_bno||'.'||cplrba_bof"low rba",cpodr_seq||'.'||cpodr_bno||'.'||cpodr_bof"on disk rba",cpods,cpodt,cphbt from x$kcccp;

设置Buffer Cache大小:

查询buffer cache中的相关参数:select component,current_size,min_size from v$sga_dynamic_components;

修改buffer cache的大小:alter system set db_cache_size=20M scope=memory;
在OLTP系统中,对于DB_CACHE_SIZE的设置,推荐配置是:db_cache_size=SGA_MAX_SIZE/2 ~ SGA_MAX_SIZE * 2/3
使用advice来确认buffer cache的大小:
select size_for_estimate "Cache Size (MB)",size_factor,buffers_for_estimate "Buffers",estd_physical_read_factor est_read_factor,
estd_physical_reads est_phy_red,ESTD_PHYSICAL_READ_TIME est_phy_red_t 
from v$db_cache_advice 
where name='DEFAULT' and block_size=(select value from v$parameter where name='db_block_size');

Block 状态:当前使用的所有块状态都存放在x$bh视图中
目前我的数据库中使用的块状态

state主要有以下几种:
0,Free:no valid block image 空闲块
1,XCUR: a current mode block,exclusive to this instance
2,SCUR:a current mode block,share with other instances
3,CR:a consistent read (stale) block image 缓存undo中的数据,来实现读一致性
4,READ:buffer is reserved for a block being read from disk 正在由data—>buffer中的读取时刻
5,WRITE:与READ相反的过程,由buffer——>data 写入到磁盘的时刻

buffer cache中常用的SQL:

一个对象占用buffer的具体情况:
select o.object_name,decode(state,0,'free',1,'xcur',2,'scur',3,'cr',4,'read',5,'mrec',6,'irec',7,'write',8,'pi') state, count(*) blocks from x$bh b,dba_objects o where b.obj=o.data_object_id and o.object_name = 'table_name' group by o.object_name, state order by blocks desc;
实验:
创建T1表,并对其进行查询此时就会产生XCUR块

对T1表某一行进行更新,此时就会产生CR块


查询一个对象使用pool的具体情况
select o.object_name,decode(state,0,'free',1,'xcur',2,'scur',3,'cr',4,'read',5,'mrec',6,'irec',7,'write',8,'pi') state,count(*) blocks from x$bh b, dba_objects o where b.obj=o.data_object_id and state <> 0 group by o.object_name,state order by blocks asc;

寻找热块:select obj object,dbarfil file#,dbablk block#,tch touches from x$bh where tch>10 order by tch asc;

整个数据文件中block的总和:select sum(block) from dba_data_block;
0 0
原创粉丝点击