ITPub博客

首页 > 数据库 > Oracle > 第79期 Oracle Buffer Busy Waits 等待事件 P3 参数详解

第79期 Oracle Buffer Busy Waits 等待事件 P3 参数详解

原创 Oracle 作者:pxbibm 时间:2026-08-10 13:58:28 0 删除 编辑

几年前,OTN 论坛上有人提出了这样一个问题: “谁知道在哪里可以找到所有不同等待事件的原因代码?”有时候问题需要更详细的描述才能避免混淆,否则可能会出现 “答非所问” 的情况。这位发帖者实际上是在询问 direct path write(直接路径写)等待事件的 P3 参数含义,而 “原因代码” 这个说法通常让人联想到 buffer busy waits(缓冲区忙等待)等待事件。这个帖子最终演变成了对 buffer busy waits的 P3 参数的简要讨论。对于 Oracle 数据库 10g R1 及以上版本,P3 参数描述了 buffer busy waits中涉及的 块类别(block class),即块的类型(来源: http://www.juliandyke.com/Internals/BlockClasses.php – 有关 10g R1 之前版本 P3 参数的含义,请参见本文底部的链接):

1  Data block
2  Sort block
3  Save undo block
4  Segment header
5  Save undo header
6  Free List
7  Extent map
8  1st level bitmap block
9  2nd level bitmap block
10 3rd level bitmap block
11 Bitmap block
12 Bitmap index block
13 File header block
14 Unused
15 System undo block
16 System undo block
17 Undo header
18 Undo block

对于块类别值大于 18 的情况,可以使用以下计算公式(将 n替换为实际的块类别值):

SELECT
  DECODE(MOD(n - 16,2),1,'撤销段的撤销头 ','撤销段的撤销块 ')||TO_CHAR(FLOOR((n - 17) / 2) + 1) DESCRIPTIONFROM
  DUAL;

例如,如果在 10046 跟踪文件中(10.1 或更高版本)出现以下内容:

WAIT #24: nam='buffer busy waits' ela= 2636 file#=7 block#=137 class#=55 obj#=0 tim=82961305208

将 n的值设为 55 代入上述 SQL 语句计算,输出结果为:

DESCRIPTION
-------------------------------
Undo Header for Undo Segment 20

这表明缓冲区忙等待是针对撤销段 20 的撤销头。那么,对于撤销头或其他任何块类别的缓冲区忙等待,我们应该怎么做呢?Oracle 文档(在 “10.3.1 buffer busy waits” 标题下)为几种块类别提供了建议。在这种情况下,下一步可能是开始监控 V$ROLLSTAT(如果未使用自动撤销管理):

SELECT
  *FROM
  V$ROLLSTATWHERE
  USN=20;

--------------------------------------------------------------------------------------------------------------------------------

块类型(Block Classes)

概述

Oracle 每一个数据块都归属于一种 块类型(Block Class)。块类型有两大核心用途:
  1. 在重做日志(redo)记录中标识对应的回滚段;
  2. 在动态性能视图 V$WAITSTAT 中提供更细粒度的等待统计,用于定位缓冲区忙等待瓶颈。

Oracle 10.2 块类型对照表

块类型编号 中文释义 英文原文
1 普通数据块 Data block
2 排序块(临时段排序数据) Sort block
3 保存撤销块(延迟回滚保存数据) Save undo block
4 段头块(段元数据头部) Segment header
5 保存撤销段头 Save undo header
6 空闲链表块(MSSM 手动段空间管理) Free list
7 区映射块(Extent 位图) Extent map
8 一级位图块(BMB 一级管理块) 1st level bitmap block
9 二级位图块 2nd level bitmap block
10 三级位图块 3rd level bitmap block
11 通用位图块 Bitmap block
12 位图索引块 Bitmap index block
13 文件头块(数据文件头部元数据) File header block
14 未使用 Unused
15 系统回滚段块(系统内部 undo) System undo block
16 系统回滚段块 System undo block
17 普通回滚段头 Undo header
18 普通回滚数据块 Undo block

大于 16 的块编号规则

编号 16 以上的数值专门分配给 普通业务回滚段,每一个回滚段占用两个块编号:一个对应回滚段头,一个对应回滚数据块。

回滚段与块编号对应表

回滚段号 回滚段头编号 回滚数据块编号
1 17 18
2 19 20
3 21 22
4 23 24
5 25 26
6 27 28
7 29
8 31 32
9 33 34
10 35 36
…… …… ……
说明:块编号不会直接存储在磁盘数据块内部,仅用于数据库诊断、性能视图、重做日志解析场景。

一、动态性能视图 V$WAITSTAT

V$WAITSTAT 视图按照 块类型汇总各类缓冲区等待耗时,视图定义底层来自内存固定表 X$KCBWAIT。

1. V$WAITSTAT 字段定义

字段名 数据类型 说明
CLASS VARCHAR2(18) 块类型文字描述
COUNT NUMBER 该类型块累计等待次数
TIME NUMBER 总等待时间(单位厘秒)

2. GV $WAITSTAT 底层视图SQL从 X$KCBWAIT 映射

SELECT view_definition FROM v$waitstat
WHERE view_name = 'GV$WAITSTAT';
SELECT 
  inst_id,
  DECODE (indx,
    1,'data block',
    2,'sort block',
    3,'save undo block',
    4,'segment header',
    5,'save undo header',
    6,'free list',
    7,'extent map',
    8,'1st level bmb',
    9,'2nd level bmb',
    10,'3rd level bmb',
    11,'bitmap block',
    12,'bitmap index block',
    13,'file header block',
    14,'unused',
    15,'system undo header',
    16,'system undo block', 
    17,'undo header',
    18,'undo block'
  ),
  count,
  time
FROM x$kcbwait
WHERE indx != 0;

3. 底层内存表 X$KCBWAIT 结构

字段 类型 含义
ADDR RAW(4) 内存地址
INDX NUMBER 块类型编号(核心字段,对应上文 1~36 等数值)
INST_ID NUMBER RAC 实例号
COUNT NUMBER 等待总次数
TIME NUMBER 累计等待厘秒

二、重做日志转储(Redo Log Dump)中的块类型

重做日志的变更记录头部会记录块类型(CLS 标识),解析 redo 转储文件时可直接看到,用于定位事务对应的回滚段。

示例 1:事务启动重做记录(OP:5.2,更新回滚段头)

CHANGE #11 TYP:0 CLS:23 AFN:2 DBA:0x00800039 OBJ:4294967295 SCN:0x0000.0026762c SEQ:  1 OP:5.2
ktudh redo: slt: 0x001e sqn: 0x000003bd flg: 0x0012 siz: 104 fbi: 0
            uba: 0x008001ae.02ee.23    pxid:  0x0000.000.00000000
  1. CLS:23:查表可知是 4 号回滚段的段头;
  2. slt:0x001e:事务插槽号,十进制 30;
  3. sqn:0x000003bd:事务序列号,十进制 957;
  4. 完整事务 ID (XID): 0x0004.01e.000003bd

示例 2:同一事务的数据修改重做记录(OP:5.1,回滚数据块)


CHANGE #15 TYP:0 CLS:24 AFN:2 DBA:0x008001ae OBJ:4294967295 SCN:0x0000.00267707 SEQ:  1 OP:5.1
ktudb redo: siz: 64 spc: 4092 flg: 0x0022 seq: 0x02ee rec: 0x24
            xid:  0x0004.01e.000003bd  
ktubu redo: slt: 30 rci: 35 opc: 11.1 objn: 16916 objd: 16916 tsn: 4
Undo type:  Regular undo       Undo type:  Last buffer split:  No 
Tablespace Undo:  No 
             0x00000000
KDO undo record:
KTB Redo 
op: 0x02  ver: 0x01  
op: C  uba: 0x008001ae.02ee.23
KDO Op code: DRP row dependencies Disabled
  xtype: XA flags: 0x00000000  bdba: 0x010018ad  hdba: 0x010018ab
itli: 1  ispac: 0  maxfr: 4858
tabn: 0 slot: 1(0x1)
每条属于同一事务的重做记录都会携带完全相同的 XID 事务编号。

示例 3:事务提交重做记录(OP:5.4)

所有事务最终提交都会生成 OP=5.4 类型重做,回滚操作结束时也会生成该类重做,逻辑等同于提交:
CHANGE #13 TYP:0 CLS:23 AFN:2 DBA:0x00800039 OBJ:4294967295 SCN:0x0000.00267707 SEQ:  1 OP:5.4
ktucm redo: slt: 0x001e sqn: 0x000003bd srt: 0 sta: 9 flg: 0x2 
ktucf redo: uba: 0x008001ae.02ee.24 ext: 2 spc: 4026 fbi: 0
通过 CLS 块号、slt 插槽、sqn 序列号即可定位该提交操作对应的全部事务变更。

补充说明

  1. 10g R1 及以上版本 buffer busy waits等待事件中 P3参数 = class#(块类型编号);
  2. 块编号 > 18 全部属于业务 undo 段,可通过 SQL 公式自动换算回滚段编号;
  3. 分析 AWR、10046 跟踪、重做日志转储时,CLS/CLASS 字段是定位热块争用的核心依据。


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/12798004/viewspace-3179345/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
Oracle ACE。ACOUG核心成员,Oracle用户组年轻专家。熟悉Oracle的体系结构,擅长Oracle数据库架构规划、SQL优化、OWI方面性能的优化。曾服务于航天、航空、机车、大型制造行业数据库的维护以及系统开发工作,开发过基于Oracle数据库的大型ERP系统。
  • 博文量
    345
  • 访问量
    2476366