当会话意图访问缓冲存储器中的数据块,而该数据块正在被其它会话使用时产生buffer busy waits事件。其它会话可能正在从数据文件向缓冲区存储器度曲同样的数据块,或正在缓冲存储器中对其进行修改。
为了确保读取器会话拥有与获得所有更改或无更改的数据块一致的映像,正在修改该数据块的会话在其标题中标记一个标志,让其他会话知道有一个更改正在进行而等候更改的的完成。
视图v$waitstat不是OWI的组件,但其为没一类缓冲区提供了有用的等待统计。遭遇buffer busy等待事件最常见的缓冲区类为块、段标题、撤消块、撤消标题。
显示一个查询v$waitstat视图的采样输出:
具体示例如下:
SELECT * FROM V$waitstat WHERE COUNT>0;
CLASS COUNT TIME
------------------ ---------- ----------
data block 4170082 1668098
segment header 116 98
undo header 916 1134
undo block 2087 1681
1、等待参数
buffer wait busy的等待参数描述如下:
P1 在Oracle 8及其以后版本的数据库里,P1显示询问数据块驻留的绝对文件号。
P2 进程需要访问的实际块号。
P3 在Oracle10g以前的版本中,着是表示等待原因的数字。Oracle在内河代码中在
多个地方用不同的原因码提交。该原因码取决于版本。
2、等待时间
100厘秒或1秒。
。 Oracle会话正在等待钉住一个缓冲区。必须在读取或修改缓冲区前将它钉住。在任何
时刻只有一个进程可以钉住一个缓冲区。
。buffer busy waits表明读/读、读/写、写/写争用。
。采取的适当措施取决于P3参数中的原因码。
在SGA中读取或修改缓冲区的会话必须首先获取cache buffers chains锁存器,并且遍历
这个缓冲区链,直到他发现必需的缓冲区头。然后,他必须以共享模式或独占模式获取
一个缓冲区锁或缓冲区头上的pin,这取决于他计划的操作。一旦缓冲区头被钉住,会话
就释放cache buffers chains锁存器,并在缓冲区自身上执行计划的操作。如果无法获
取一个pin,会话就在buffer busy waits等待事件上等待。这种等待时间不会应用于在
会话的私有PGA中执行的读取或写入操作。
3、诊断的原因、诊断和动作
。表示为什么进程无法获得一个缓冲区pin的主要原因码。
。buffer busy waits等待时间需要的块类。
。和buffer busy waits时间相关的SQL语句。
。缓冲区所属的段。
——查找等待块类型
SELECT 'segment Header' CLASS,
a.Segment_Type,
a.Segment_Name,
a.Partition_Name
FROM Dba_Segments a,
V$session_Wait b
WHERE a.Header_File = b.P1
AND a.Header_Block = b.P2
AND b.Event = 'buffer busy waits'
UNION
SELECT 'freelist Groups' CLASS,
a.Segment_Type,
a.Segment_Name,
a.Partition_Name
FROM Dba_Segments a,
V$session_Wait b
WHERE b.P2 BETWEEN a.Header_Block + 1 AND (a.Header_Block + a.Freelist_Groups)
AND a.Header_File = b.P1
AND a.Freelist_Groups > 1
AND b.Event = 'buffer busy waits'
UNION
SELECT a.Segment_Type || ' Block' CLASS,
a.Segment_Type,
a.Segment_Name,
a.Partition_Name
FROM Dba_Extents a,
V$session_Wait b
WHERE b.P2 BETWEEN a.Block_Id AND a.Block_Id + a.Blocks - 1
AND a.File_Id = b.P1
AND b.Event = 'buffer busy waits'
AND NOT EXISTS (SELECT 1
FROM Dba_Segments
WHERE Header_File = b.P1
AND Header_Block = b.P2);

