当会话想要访问缓冲存储器中的数据块,而该数据块正在被其它会话使用时产生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 在Oracle8及极其以后版本的数据库里,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);
◆ 带有原因码130的数据块(类#1)争用
如果buffer busy waits的等待事件主要集中在数据块(类#1)上,并且原因码130,则
表明应用程序运行在同一时刻查询相同数据集的多个会话,采用如下三件事最小化问题:
§减少并发级别或该表在运行现成直接内分区工作的方法。
§优化SQL语句,减少物理读取和逻辑读取的数量。
§增加freeLists和freeList Groups的数量。
◆ 带有原因码220的数据块(类#1)争用
多个会话同时在相同的对象上DML。采用如下三件事最小化问题:
§减少并发级别或改变划分部分的方法。
§减少块中行的数量。
§在另一个具有较小块尺寸的表空间中重新构建对象(Oracle 9i或以上版本)。
可以使用较大的PCTFREE重新构建表或索引。可以使用命令改变表以最小化每个块的最
小行数:
ALTER TABLE table_name MINIMIZE RECORDS_PER_BLOCK;
从Oracle 9i开始,可以在另外一个具有较小的块尺寸的表空间中移动或重新构建对象。
虽然这些动作可以最小化buffer busy waits问题,但是他们无疑将增加全表扫描时间
和磁盘空间利用率。常言道,世上没有免费的午餐。
◆ 数据段头(类#4)的争用
如果buffer busy waits的等待时间主要集中在数据段头(即表或索引段头,并且不是
插销段头)上,这意味着数据库中的一些表或索引具有高段头活动。如下解决问题:
§增加已经确定对象的进程FreeLists和FreeList Groups的数量。
§确保PctFree和PctUsed之间内的间隙不会太小。
§确保下一个区尺寸不会太小。
如果不希望混浠FreeLists和FreeList Groups,可以依靠自动段空间管理(Automatic
Segment Space Management,ASSM)特性,以分散从插入语句中引入的数据(9i特性)。
◆ 撤消段都(类#17)的争用
如果buffer busy waits等待时间主要集中在撤消段头上,这表明数据库中的回滚段
过少,或者他们的尺寸太小,从而造成对段头的频繁更新。如果在Oracle 9i中引入的系
统管理撤消,就不需要处理这种问题,因为Oracle将根据需要增加额外的撤消段。
◆ 撤消块的争用(类#18)
如果buffer busy waits等待时间主要集中在撤消块上,这通常意味着多个并发会话同
时查询更新的数据。当应用程序可以在不同的时间内查询和DML时,这种问题就不会存在。
◆ 系统级诊断
--文件等待次数
SELECT b.File_Id,
b.File_Name,
a.COUNT
FROM X$kcbfwait a,
Dba_Data_Files b
WHERE a.Indx = b.File_Id-1
AND a.COUNT > 0
ORDER BY a.COUNT;