
好的,我们来对 Oracle 19C 数据库中的 V$HANG_INFO 动态性能视图进行一次全面、深入的解析。这个视图是诊断数据库“挂起”或严重性能瓶颈的终极工具之一。
1. 作用与概述
V$HANG_INFO 视图用于检测和分析数据库中的“挂起”(Hang)或严重阻塞情况。它提供了一种结构化的方式来识别会话之间的阻塞链,并帮助定位导致系统停滞的根本原因。
- 核心目的: 它不是用来监控常规等待事件的,而是专门用于诊断那些导致数据库部分或整体失去响应、会话长时间卡住的严重问题。
- 数据生成: 该视图的内容不是持续存在的。它通常是在执行特定的诊断操作(如运行
ORADEBUG HANGANALYZE)或数据库实例自动检测到严重问题时,动态生成一份分析快照。 - 输出内容: 该视图展示了会话之间的等待关系图(Wait Graph),以树形结构清晰地显示出“谁在阻塞谁”,并指出阻塞的资源和等待的事件。
2. 使用场景
此视图在以下紧急场景中至关重要:
-
数据库挂起诊断:
- 当大量用户报告他们的会话停止响应,或整个数据库操作极其缓慢近乎停滞时,DBA 使用此视图来识别阻塞链的根源。
-
严重性能瓶颈分析:
- 当
V$SESSION和V$SESSION_WAIT显示大量会话在等待同一个或少数几个事件时,使用此视图可以快速理清这些会话之间的依赖和阻塞关系。
- 当
-
死锁与复杂阻塞:
- 虽然Oracle能自动解决普通的行级死锁,但更复杂的死锁(如由存储过程逻辑、队列锁等引起的)或长时间的串行阻塞,需要借助此视图进行深入分析。
-
Proactive Health Check (可选):
- 在系统压力较大时,也可以主动运行hang analyze来检查是否存在潜在的阻塞风险。
3. 字段含义详解
V$HANG_INFO 视图的字段描述了阻塞链中的会话、它们的关系以及等待的详细信息。
| 字段名称 | 数据类型 | 含义说明 |
|---|---|---|
| BLOCKING_TREE | VARCHAR2(512) | 这是最关键的字段。它以一种可视化的树形结构展示会话之间的阻塞关系。 • <- 表示“被…阻塞”• \ 表示一个分支• 数字和 :表示树的层级例如: <-123 <-456 表示会话456阻塞了会话123。 |
| BLOCKING_SESSION | NUMBER | 直接阻塞当前会话的会话标识符(SID)。如果为NULL,则表示该会话是阻塞链的根,或者没有被其他会话阻塞。 |
| BLOCKED_SESSION | NUMBER | 当前被阻塞的会话标识符(SID)。 |
| BLOCKING_CHAIN_SIGNATURE | VARCHAR2(128) | 阻塞链的签名哈希值。用于唯一标识一个特定的阻塞场景。相同的签名意味着是同一个根本原因引起的挂起。 |
| CHAIN_ID | NUMBER | 当前阻塞链的唯一标识符。一个挂起事件可能包含多个独立的阻塞链。 |
| CHAIN_SIGNATURE | VARCHAR2(128) | 阻塞链的详细签名,比 BLOCKING_CHAIN_SIGNATURE 包含更多信息。 |
| WAIT_EVENT | VARCHAR2(64) | 被阻塞会话正在等待的事件名称(如:enq: TX - row lock contention)。 |
| WAIT_TIME | NUMBER | 等待时间(单位:秒)。 |
| SESSION_ID | NUMBER | 会话的SID。通常是 BLOCKED_SESSION 的值。 |
| SERIAL# | NUMBER | 会话的序列号(SERIAL#)。与 SESSION_ID 一起唯一标识一个会话。 |
| PID | NUMBER | 操作系统进程标识符(PID)。 |
| PROCESS_NAME | VARCHAR2(5) | 进程名称(如:ora, java)。 |
| SQL_ID | VARCHAR2(13) | 当前正在执行的SQL语句的ID。可与 V$SQL 关联查看SQL文本。 |
| SQL_CHILD_NUMBER | NUMBER | SQL语句的子游标号。 |
| MODULE | VARCHAR2(64) | 会话的模块名称(通常由应用程序设置)。 |
| ACTION | VARCHAR2(64) | 会话的动作名称(通常由应用程序设置)。 |
| CLIENT_IDENTIFIER | VARCHAR2(64) | 客户端标识符。 |
| DETECTION_TIME | DATE | 检测到挂起/生成此分析结果的时间。 |
| ORIGIN | VARCHAR2(64) | 此分析结果的来源。例如:ORADEBUG HANGANALYZE 或 DIAG Process。 |
| RESOLVED | VARCHAR2(5) | 指示此挂起问题是否已被解决(YES/NO)。 |
4. 相关视图与基表
-
相关动态性能视图:
V$SESSION/V$SESSION_WAIT: 这是诊断阻塞问题的起点。通过BLOCKING_SESSION字段可以初步找到谁在阻塞谁。V$HANG_INFO是对这些信息的自动化、图形化深度分析。V$LOCK: 查看当前持有的锁和申请的锁,是理解enq:等待事件的基础。V$SQL: 通过SQL_ID关联,查看阻塞链中会话正在执行的具体SQL语句。DBA_HIST_ACTIVE_SESS_HISTORY(ASH): 用于查询历史挂起事件,但不如V$HANG_INFO的实时分析直接和清晰。V$DIAG_HANG_INFO: 在某些版本中,这可能是一个更底层或相关的诊断视图。
-
基表(Underlying Base Table):
V$HANG_INFO没有传统意义上的持久化基表。它的数据是在调用ORADEBUG HANGANALYZE或由数据库诊断进程(DIAG)自动触发时,动态生成在内存中的一份快照。- 执行 hang analyze 时,Oracle 会:
- 暂停系统状态片刻(以一种尽可能减少影响的方式)。
- 遍历所有活动会话,构建一个等待图(Wait Graph),分析循环等待或长等待链。
- 将分析结果格式化并输出到跟踪文件(通常位于
diag/rdbms/<db_name>/<instance_name>/trace目录下,文件名包含_hang_)。 - 同时,也将分析结果的摘要信息填充到
V$HANG_INFO视图中,供DBA直接查询。
- 因此,该视图的内容是瞬态的,每次分析都会覆盖上一次的结果。
5. 底层详细原理
-
** Hang Analyze 的工作机制**:
- 当调用
ORADEBUG HANGANALYZE时,它会向数据库实例发送一个指令。 - 一个专门的诊断进程(DIAG)会接管并执行以下操作:
- 获取系统状态: 以一种协调的方式,快速捕获所有活动会话的当前状态(包括它们正在等待什么、持有什么资源、被谁阻塞等)。
- 构建等待图: 基于收集到的数据,构建一个有向图。节点是会话,边表示“阻塞”关系(Session A -> waits for -> Resource held by -> Session B)。
- 分析图: 查找图中的环(Cycle,即死锁)和长链(Long Chain,即串行阻塞)。
- 生成报告: 将分析结果以文本形式写入跟踪文件,并以结构化的方式填充到
V$HANG_INFO视图中。
- 当调用
-
BLOCKING_TREE的生成:- 这是算法的核心输出。Oracle 从那些没有被其他会话阻塞的“根”会话(通常是空闲会话或真正持有资源的会话)开始,递归地向下遍历,为每个被阻塞的会话构建一个树形字符串。
- 这个字符串直观地展示了整个阻塞的层次结构,使DBA一眼就能看出问题的全貌。
-
与死锁检测的区别:
- Oracle 后台进程
LMON会定期检测并解决普通的行级死锁(通过回滚其中一个事务)。 HANGANALYZE更强大,它能检测到LMON可能无法自动解决的复杂挂起情况,例如由闩锁(latch)、互斥量(mutex)、缓冲区忙等待等引起的挂起,或者虽然不构成死锁但导致系统性能雪崩的长时间阻塞。
- Oracle 后台进程
6. 相关知识点介绍
-
ORADEBUG工具: 这是一个非常强大但危险的Oracle诊断工具,通常只在Oracle支持人员的指导下使用。生成hang analyze的命令是:-- 需要SYSDBA权限 SQL> ORADEBUG hanganalyze 3 -- 级别3是常用级别,表示收集详细信息。 -- 执行后,即可查询 V$HANG_INFO 视图。 -
常见挂起原因:
- 锁竞争: 未提交的事务长期持有行锁(
enq: TX - row lock contention)。 - 闩锁/互斥量竞争: 热点块、共享池/缓冲区库缓存争用(
latch: shared pool,library cache: mutex X)。 - IO 问题: 存储性能瓶颈导致所有会话等待
db file sequential read或db file scattered read。 - 繁忙的日志: 日志文件同步慢(
log file sync)会阻塞所有提交操作。 - 系统资源耗尽: CPU、内存耗尽导致调度异常。
- 锁竞争: 未提交的事务长期持有行锁(
-
安全警告: 在系统负载极高时,运行
ORADEBUG HANGANALYZE可能会加剧系统负担,导致“雪上加霜”。因此,操作需谨慎。
7. 常用查询 SQL
1. 获取完整的挂起分析报告(最常用)
在执行 ORADEBUG HANGANALYZE 3 后,立即运行此查询。
SELECT blocking_tree,
blocked_session,
blocking_session,
wait_event,
wait_time,
sql_id,
module,
action
FROM v$hang_info
ORDER BY blocking_tree, blocked_session;
2. 查找阻塞链的根源(顶级阻塞者)
SELECT DISTINCT blocking_session
FROM v$hang_info
WHERE blocking_session IS NOT NULL
MINUS
SELECT blocked_session
FROM v$hang_info;
-- 这个查询找到那些阻塞别人但自己不被阻塞的会话,他们很可能是根源。
3. 查看特定阻塞链的详细信息
SELECT *
FROM v$hang_info
WHERE chain_id = 1 -- 假设Chain ID是1
ORDER BY blocking_tree;
4. 关联 V$SQL 获取阻塞者正在执行的SQL
SELECT h.blocking_tree,
h.blocked_session,
h.wait_event,
s.sql_text
FROM v$hang_info h
LEFT JOIN v$sql s ON h.sql_id = s.sql_id
WHERE h.blocking_session IS NOT NULL;
5. 检查挂起是否解决(比较不同时间点的分析)
-- 第一次分析
-- ORADEBUG HANGANALYZE 3
-- SELECT ... FROM V$HANG_INFO;
-- 采取干预措施(如kill会话)后,再次分析
-- ORADEBUG HANGANALYZE 3
SELECT detection_time, chain_id, blocked_session, resolved
FROM v$hang_info
ORDER BY detection_time DESC;
-- 观察 RESOLVED 字段和新的分析中是否还有阻塞链。
总结
V$HANG_INFO 是Oracle数据库提供的一个高级诊断“CT机”。它不用于日常监控,而是在系统出现严重性能危机时,用于进行一次性、深层次的病理分析。
它的核心价值在于:
- 可视化阻塞关系: 通过
BLOCKING_TREE字段,将复杂的会话等待关系以一目了然的树形图呈现,极大简化了诊断过程。 - 定位根本原因: 快速准确地找到导致系统挂起的“罪魁祸首”会话和SQL。
- 指导解决措施: 分析结果直接指导DBA采取最有效的措施,例如终止哪个会话可以最有效地解除阻塞。
掌握 V$HANG_INFO 和 ORADEBUG HANGANALYZE 的使用,是DBA从“普通运维”走向“性能专家”和“故障排查医生”的重要标志。它是在数据库生命攸关时刻的终极诊断工具。
欢迎关注我的公众号《IT小Chen》

被折叠的 条评论
为什么被折叠?



