Documente Academic
Documente Profesional
Documente Cultură
结论:
db cache 用尽以及 IO 性能低下的情况下,数据库不能及时地将缓存中的脏数据块写入到数
据文件以腾出内存区域,因此导致了大量的等待,其中 IO 在 Free buffer waits 事件出现的
时候基本上达到满负荷,DATA BUFFER 虽然增加过但仍然相对过小,导致很多新的需求
根本无法请求内存,因此 Free buffer waits 事件频繁出现。
建议:
对 TOP SQL 进行优化,后面会有针对 TOP SQL 的 cache 及 mview 的案例。
如果不能优化,那么 Free buffer waits 事件的操作建议仍然是增加 DATA BUFFER 的大小。
当会话意图访问缓冲存储器中的数据块,而该数据块正在被其它会话使用时产生 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);
系统级诊断 ——文件等待次数
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;