面试宝典:介绍下Oracle数据库动态性能视图 V$SESSION_WAIT_HISTORY

在这里插入图片描述

好的,我们来对 Oracle 19c 数据库中的 V$SESSION_WAIT_HISTORY 动态性能视图进行最全面、最深入的解析。

V$SESSION_WAIT_HISTORY 是一个极其有价值的性能诊断视图,它提供了每个活动会话最近发生的多次等待事件的详细历史记录。与 V$SESSION_WAIT(只显示当前或最后一次等待)和 V$SESSION_EVENT(只显示累计值)不同,它让你能够像“回放录像”一样,查看会话刚刚经历过什么,这对于诊断短暂的、间歇性的性能问题至关重要。


一、字段含义详解

字段名数据类型描述重要说明与示例
SIDNUMBER产生等待事件的会话标识符 (Session Identifier)。V$SESSION.SID 对应。
SEQ#NUMBER等待序列号。在一个会话内,每次等待都会分配一个唯一的、递增的序列号。用于判断等待事件发生的先后顺序。序列号越大,事件发生的时间越近。
EVENTVARCHAR2(64)等待事件的名称。例如:'db file sequential read', 'enq: TX - row lock contention', 'latch: shared pool'
P1TEXTVARCHAR2(64)等待事件第一个附加参数的文本描述。例如:'file#'
P1NUMBER等待事件第一个附加参数的具体数值。其含义由 EVENT 决定。例如,对于 'db file sequential read'P1 代表文件号 (file_id)。
P2TEXTVARCHAR2(64)等待事件第二个附加参数的文本描述。例如:'block#'
P2NUMBER等待事件第二个附加参数的具体数值。对于 'db file sequential read'P2 代表起始块号 (block_id)。
P3TEXTVARCHAR2(64)等待事件第三个附加参数的文本描述。例如:'blocks'
P3NUMBER等待事件第三个附加参数的具体数值。对于 'db file sequential read'P3 代表要读取的块数。
WAIT_TIMENUMBER此次等待的实际持续时间(单位:百分之一秒,即 10ms)。> 0: 实际的等待时间。
0: 等待时间极短,无法计量。
-1: 时间统计未开启 (TIMED_STATISTICS=false)。
-2: 参数已废弃。
WAIT_COUNTNUMBER该等待事件发生的次数。注意:此视图中的 WAIT_COUNT 指的是该特定事件序列(由 SID, EVENT, P1, P2, P3 确定)在历史记录中出现的次数,并非会话累计值。用于判断一个相同的等待是否在短时间内反复发生。

二、核心原理与底层机制

1. 数据来源与底层基表

V$SESSION_WAIT_HISTORY 是一个动态性能视图,其数据来源于 SGA 中的一个内存循环缓冲区。这个缓冲区为每个活动会话预留了一小块空间(通常可存储最近 10 次等待事件的信息)。

其底层源是 X$ 表,通常是像 X$KSWHST 这样的底层结构。这些 X$ 表直接映射了 SGA 中用于存储会话等待历史的内存区域。DBA 无需直接查询 X$ 表,V$SESSION_WAIT_HISTORY 提供了更友好、稳定的接口。

2. 详细工作机理
  1. 会话初始化:当一个会话变为活动状态时,Oracle 在 SGA 中为其分配一个小的、固定大小的缓冲区(如 10 个槽位)来记录等待历史。
  2. 等待事件发生:每当会话完成一个非空闲等待事件(Non-idle wait event)时:
    • Oracle 内核将该事件的详细信息(EVENT, P1, P2, P3, WAIT_TIME 等)写入为该会话分配的缓冲区的下一个槽位
    • 如果缓冲区已满(例如已存满10次等待),则新的记录会覆盖最旧的那条记录(FIFO,先进先出)。因此,这个视图永远只保存最近的 N 次等待
    • SEQ# 会递增,WAIT_COUNT 会对完全相同的等待事件进行计数。
  3. 数据查询:当你查询 V$SESSION_WAIT_HISTORY 时,Oracle 实际上是直接从这个 SGA 的内存缓冲区中读取数据,因此它的速度非常快,并且显示的是近乎实时的信息。
  4. 会话断开:当会话断开连接后,其对应的等待历史缓冲区被释放,该会话的记录将从视图中消失。
3. 与 ASH (Active Session History) 的关系

V$SESSION_WAIT_HISTORYV$ACTIVE_SESSION_HISTORY (ASH) 功能上有相似之处,但侧重点不同:

  • V$SESSION_WAIT_HISTORY
    • 深度:提供每个会话最近最多10次等待的非常详细的信息(包括精确的 P1/P2/P3 参数)。
    • 广度:仅覆盖极短的时间窗口(仅最后几次等待)。
    • 开销:几乎无额外开销,是内核等待机制的自然副产品。
  • V$ACTIVE_SESSION_HISTORY
    • 深度:每秒采样一次,只记录会话在采样点时是否在等待以及等待什么事件,不包含每次等待的精确时长和详细参数(但包含 SQL_ID, 对象号等更多会话上下文)。
    • 广度:默认在内存中保存约1小时的数据,提供更长的历史视角。
    • 开销:有轻微的采样开销。

总结V$SESSION_WAIT_HISTORY 用于微观分析,查看会话刚刚发生的具体等待细节;ASH 用于宏观分析,回溯一段时间内的性能问题。两者可结合使用。


三、常用查询 SQL 示例

  1. 查看某个会话(SID=135)最近的等待历史

    SELECT sid, seq#, event, p1text, p1, p2text, p2, p3text, p3,
           wait_time, wait_count
    FROM v$session_wait_history
    WHERE sid = 135
    ORDER BY seq# DESC; -- 最新的等待排在前面
    
  2. 诊断特定的短暂等待:查找所有经历过 ‘enq: TX - row lock contention’ 的会话及其历史

    SELECT swh.sid, s.username, s.osuser, s.program, s.sql_id,
           swh.seq#, swh.event, 
           swh.p1, swh.p2, swh.p3, -- 这些参数对解码锁信息至关重要
           swh.wait_time, swh.wait_count
    FROM v$session_wait_history swh
    JOIN v$session s ON swh.sid = s.sid
    WHERE swh.event = 'enq: TX - row lock contention'
    ORDER BY swh.sid, swh.seq# DESC;
    
  3. 结合参数解读:将等待事件与具体对象关联(例如,查找I/O等待对应的对象)

    SELECT swh.sid, swh.seq#, swh.event, 
           swh.p1 AS file_id, 
           swh.p2 AS block_id,
           DO.owner, DO.object_name, DO.object_type
    FROM v$session_wait_history swh
    LEFT JOIN dba_objects DO ON (
        DO.data_object_id = (
            SELECT data_object_id 
            FROM dba_extents 
            WHERE file_id = swh.p1 
            AND swh.p2 BETWEEN block_id AND block_id + blocks - 1
            AND ROWNUM = 1
        )
    )
    WHERE swh.event IN ('db file sequential read', 'db file scattered read')
      AND swh.wait_time > 5 -- 只查等待时间较长的
    ORDER BY swh.wait_time DESC;
    

    注意:此查询对性能有一定影响,请在必要时使用。

  4. 查找重复出现的短等待(高频率等待)

    SELECT sid, event, p1, p2, p3, wait_count, wait_time
    FROM v$session_wait_history
    WHERE wait_count > 3 -- 相同的等待短时间内发生了多次
    ORDER BY wait_count DESC;
    

四、主要应用场景

  1. 诊断间歇性阻塞或挂起
    用户报告“应用偶尔会卡一下,但马上又好了”。DBA 可以在问题发生后立即连接到数据库,查询相关会话的 V$SESSION_WAIT_HISTORY,查看其在“卡顿”期间到底经历了什么等待(例如,一个短暂的行锁等待或一个缓慢的I/O),即使该等待现在已结束。

  2. 分析具体的等待事件参数
    V$SESSIONAWR 报告显示系统存在大量的 buffer busy waits 时,你可以使用此视图找到最近发生这种等待的会话,并通过 P1 (file#), P2 (block#) 参数精确定位到热点块,进而分析原因。

  3. 验证问题是否解决
    在实施了一个优化措施(如调整SQL、扩容等)后,可以持续监控相关会话的等待历史,观察之前频繁出现的、导致性能问题的等待事件是否已经消失或等待时间大幅缩短。

  4. 关联分析
    将一个会话的等待历史与其当前执行的 SQL (V$SESSION.SQL_ID)、会话程序信息等结合,可以建立从“应用请求”到“数据库资源等待”的完整证据链。


五、相关视图

  • V$SESSION:提供会话的基本状态和信息(如 USERNAME, STATUS, SQL_ID),是关联分析的起点。
  • V$SESSION_WAIT:显示会话当前或最后一次的等待信息。V$SESSION_WAIT_HISTORY 是其历史的扩展。
  • V$ACTIVE_SESSION_HISTORY (ASH):提供所有活动会话的历史采样信息,时间范围更广,但细节深度不如 V$SESSION_WAIT_HISTORY
  • DBA_EXTENTS / DBA_OBJECTS:用于将 P1 (file#) 和 P2 (block#) 参数解析为具体的表、索引等对象名称。
  • V$EVENT_NAME:提供等待事件的元数据,包括参数的含义(PARAMETER1, PARAMETER2, PARAMETER3)。

总结V$SESSION_WAIT_HISTORY 是 Oracle DBA 武器库中一把精准的“手术刀”,它提供了其他视图无法提供的、极细时间粒度下的会话等待细节,是解决棘手性能问题的利器。其核心价值在于能够回溯刚刚发生但已结束的等待事件

欢迎关注我的公众号《IT小Chen

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值