首页 > Oracle > 与buffer cache相关的等待事件—free buffer waits等待事件!
2014
01-22

与buffer cache相关的等待事件—free buffer waits等待事件!

前面简单说了2个等待事件,今天我们来看下第三个free buffer waits等待事件。当一个数据块在被读入到buffer cache之前,oracle必须为该数据块获得一个对应的可用的内存数据块,当LRU链表上无法发现一个可用的内存数据块,都不能剔除的时候,这时该session就必须等待free buffer waits事件。

所以当一个进程需要一个可用的内存数据块时,前台进程会先扫描LRU链表,直到达到一个限定值(隐藏参数_db_block_max_scan_pct的值,该值表示已经扫描的buffer header数量占整个LRU链表上的buffer header的总数量),如果达到整个限定值后还没找到一个可用的内存数据块,该前台进程就会触发DBWR进程以便清空一些脏数据块,从而使得在辅助LRW链表上能够挂上一些可用的内存数据块,所以在DBWR进程工作时,该前台进程就必须等地啊free buffer waits事件。

oracle每次请求可用内存数据块的请求次数可用在v$sysstat视图中的free buffer requested看到,可用在v$system_event视图中的free buffer waits的total_waits看到每次请求可用的内存数据块失败的次数,在v$sysstat中的free buffer inspected表示oracle为了找到可用内存数据块所跳过的数据块的个数,如果buffer cache有很多空的数据块,那么该值为0.如果free buffer inspected相对free buffer requested来说很高,就说明oracle进程需要扫描更多的LRU链表上的数据块才可以找到可用的数据块。

但是在这个过程中只跳过了2983596(free buffer inspected)个数据块,二者相差2个数量级。说明系统很容易就找到可用的内存数据块。

一般情况下有如下原因导致一个session话费了很多时间等待free buffer waits等待事件:

1) 低效率的SQL语句:对于那些引起很大逻辑读的SQL语句(v$sql里的disk_reads),那些SQL语句可能进行了全表扫描,索引全扫描、或者通过了不正确的索引扫描表等。调整这些SQL语句以降低逻辑读。

2) DBWR进程不够多:也可以通过增加DBWR checkpoints的个数来降低free buffer waits。9i下,可以通过减小fast_start_mttr_target参数来缩短MTTR,从而增加DBWR进程启动的次数。然而,这也有可能引起进程等待write complete waits事件。

3) I/O子系统太慢。

4) 延迟的块清除(block clearouts):通常发生的情形是,晚上向数据库导入了一个很大的表。然后早上运行应用系统时,会发现有有进程在等待buffer busy waits。这是因为第一个访问该表的进程将进行一个延迟的块清除,而这会导致free buffer waits等待事件。解决方法是在导入表完毕以后,执行一句全表扫描,比如通常是:select count(*) from该大表。这样在后面的进程再次访问的时候就不会产生free buffer waits等待事件了。

5) buffer cache太小:遇到free buffer waits事件,首先想到的就是增加buffer cache的大小。

最后编辑:
作者:Jerry
一个积极向上的小青年,热衷于分享--Focus on DB,BI,ETL