【TUNE_ORACLE】等待事件之“buffer busy waits”

定义

当会话想要访问缓冲区缓存中的数据库块但由于缓冲区“繁忙”而无法访问时,会发生这种等待。 可能发生这种情况的两种主要情况是:

1. 当一个会话将数据块从磁盘读到内存中,发现内存没有空闲的内存块。

2. 发生一致性读时,由于需要创建某个时刻的前镜像,就需要在内存中申请内存块,如果没有空闲的内存块,就会发生该等待事件。

当数据库中存在热块时,即用户频繁读取或者修改某个数据块时,会发生该等待事件。

 

对于自身范围内产生的等待

1. 查看动态性能视图V$SESSION_WAIT涉及到的“buffer busy waits”参数

P1 = file#

P2 = block#

P3 = id

注:

file#:包含等待会话所需块的数据文件的文件号。

block#:等待会话想要访问file#中的块号。

id:官方释义如下

 

2. 等待时间

正常等待时间为1秒。如果会话在上次等待期间一直在等待独占缓冲区,那么它将等待3秒。会话将保持超时/等待,直到它申请到缓冲区。

 

3. 寻找“Blockers”

找到阻塞过程可能非常困难,因为所需的信息没有外化。如果P3显示“buffer busy waits”正在等待块读取完成,则阻塞会话可能正在等待I/O等待(例如:“db file sequential read”或“db file scattered read”)用于相同的file#和block#。

如果等待是由于缓冲区处于不兼容模式,那它应该很快被释放。

 

对于系统范围内产生的等待

如果等待缓冲区所非常耗时,那么最好确定哪个段正在发生争用。Bstat/estat或STATSPACK报告的“缓冲区繁忙等待统计”部分显示了哪些块类型看到最多的争用。使用以下SQL查询等待时间最多的块:

 SELECT time, count, class
    FROM V$WAITSTAT
   ORDER BY time,count;

使用以下SQL查看发生等待时块的保存位置:

 SELECT kcbwhdes, why0+why1+why2 "Gets", "OTHER_WAIT"
    FROM x$kcbsw s, x$kcbwh w
   WHERE s.indx=w.indx
     and s."OTHER_WAIT">0
   ORDER BY 3;

 

用下面的SQL可以查看等待最多的文件,因此通过组合上述信息,我们知道哪个文件中的什么块类型导致等待:

SELECT count, file#, name
    FROM x$kcbfwait, v$datafile
   WHERE indx + 1 = file#
   ORDER BY count;

 

可以使用如下查询查看每个文件中的段:

SELECT distinct owner, segment_name, segment_type
    FROM dba_extents
   WHERE file_id= &FILE_ID;

 

如果列出的类型有大量段,可重复运行以下语句并收集输出,并每经过一段时间对结果进行排序以查看哪些文件和块显示争用:

SELECT p1 "File", p2 "Block", p3 "Reason"
    FROM v$session_wait
   WHERE event='buffer busy waits';

 

减少等待和等待时间的方法

由于该等待事件是由于对特定块的争用,所以消除块的争用的原因是最好的方式。 请注意,数据块的“buffer busy waits”通常是由于多个进程重复读取相同的块(例如:如果很多人扫描相同的索引),第一个会话快速处理缓冲区缓存中的块,然后块必须从磁盘读取。其他会话(扫描相同的索引)快速“赶上”并想要当前正在从磁盘读取的块,他们会等待缓冲区腾出空间,因为有人已经在读取该块。

对特定类型的争用可以参考以下方法来减少争用:


请使用浏览器的分享功能分享到微信等