Buffer Busy Waits的两个结论

   官方文档:

    This wait indicates that there are some buffers in the buffer cache that multiple processes are attempting to access concurrently. Query V$WAITSTAT for the wait statistics for each class of buffer. Common buffer classes that have buffer busy waits include data block, segment header, undo header, and undo block.

   对Buffer Busy Waits进行了次深入的分析,得到结论如下:
一、兼容模式:
    10G后的Buffer Busy Waits已经和以前大不一样了。不再是以前的读、写互相阻塞,或写、写互相阻塞。也不是有些网友说的读、写不阻塞,只有写、写阻塞。
    真实的Buffer Busy Waits,有如下两种情况:
    (1)、两个进程一同写一个Buffer,这是写、写阻塞。
    (2)、一个进程在写一个Buffer,另一个进程读。读的进程会有等待。这是写阻塞读。

    现在,Buffer Busy Waits,只有这两种情况了。
    有人说,如果一个进程先开始读一个Buffer,另一个进程又要写一个Buffer,这种情况下Oracle如何处理?读会阻塞写吗?答案是,不会。写的操作可以不需等待的马上开始,而正在进行的读操作,则会中止开始等待Buffer Busy Waits。
    这就是为什么在Buffer busy waits升高时,查找SQL语句,等待Buffer busy waits的大多数会话都是Select,很少有DML。因为DML不会被Select阻塞,只有DML间会互相阻塞。关于这一点,做个简单的测试就可以证明:
在会话1运行如下脚本:
declare
    j number;
begin
for i in 1..3000000 loop
    select id into j from a1 where rowid='AAAChqAAEAAAAAMAAA';
end loop;
end;
/


反复读取某一行。
在会话2运行如下脚本:
begin
for i in 1..300 loop
    update a1 set id=id+0 where rowid='AAAChqAAEAAAAAMAAA';
end loop;
commit;
end;
/


然后在V$SESSION_EVENT中查看两个Session的Buffer busy waits等待。


会话1反复查询一行,会话2反复更新同一行300次,两个会话应该各有少许的Buffer busy waits,对吧。
但实际情况不是这样的。会话2一般不会有,只有会话1会有Buffer busy wait等待。


这就是写阻塞读、读在大部分情况下,不会阻塞写。
当然,除了这种证明方法外,还有更加精确的方法,证明写阻塞读、读不阻塞写,我放在后面深入部分。
二、减少Buffer busy waits的另类方法
    我在前一篇文章中,提到从宏观上减少Buffer busy waits等待的另一种方法,就是加快日志文件的写速度,使用更快的设备,放存Redo文件。原理是什么呢:
    进程在Buffer Cache中的某个Buffer加的锁,我称之为Buffer Pin。进程修改一个Buffer的过程,可以粗略的描述如下:
(1)、加Cache buffers chains latch(下文中简称为CBC Latch)
(2)、加Buffer Pin
(3)、释放CBC Latch。
(4)、将Redo信息拷贝到共享池的公有Redo区,或Log Buffer中。
(5)、修改Buffer中的内容
(6)、加CBC Latch
(7)、释放Buffer Pin
(8)、释放CBC Latch
      1至3步,加CBC Latch,是为了加Buffer Pin。6至8步的CBC Latch,是释放Buffer pin。
      在加了Buffer Pin之后,主要要做的事情有两个,一个是修改Buffer中的内容。另一个,是拷贝Redo信息。
      减少Buffer busy waits,其实就是缩短Buffer Pin的持有时间。缩短Buffer Pin的持有时间,我们可以做的事情有两个,一个是加快第5步,“修改Buffer中的内容”。或者,是第4步,拷贝Redo信息。
     在第5步,Oracle修改Buffer中内容,使用的是memcpy函数,这一步没什么好优化的了。但第4步拷贝Redo信息,还是可以调优的。
    在一定条件下,前台进程要将Redo信息直接拷贝到Log Buffer,而不是共享池中的私有Redo区。此时,如果Log Buffer中没有空间,遇到Log Buffer Space等待,前台进程要呼叫LGWR刷新Log Buffer。一旦出现这种情况,Buffer Pin的持有时间不得不变的很长,直到Log buffer中有空间了,拷贝Redo信息结束,前台进程修改完Buffer中的内容。然后才会释放Buffer  pin。

    因此,如果我们可以保证Log Buffer中总是有空间可用,就可以减少Log Buffer Space,从而减少前台进程呼叫LGWR的次数,从而在某些时候减少Buffer Pin的持有时间。这就是我在上一篇文章中,描述的加快Redo文件写速度,减少Buffer Busy Waits的原理。

    转自:http://www.itpub.net/forum.php?mod=viewthread&tid=1593488


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值