ASH dump文件并非v$active_session_history的直接备份,而是内存ASH buffer的秒级二进制切片,仅含session_id、event、sql_id等有限字段,无SQL上下文、绑定变量及毫秒精度,不可用于AWR式聚合分析。

ASH dump文件不是v$active_session_history快照
很多人误以为导出的 ASH dump 文件是数据库里 v$active_session_history 的直接备份,其实它只是 Oracle 内部用于诊断的二进制转储(类似堆栈快照),不带 SQL 解析上下文、不包含绑定变量值、也不保留完整的会话生命周期链。它本质是内存中 ASH buffer 的“快照切片”,只记录采样时刻的 session_id、event、wait_class、sql_id、sample_time 等有限字段,且时间精度被截断为秒级(丢失毫秒部分)。
所以别指望用它还原完整 SQL 执行链或做 AWR 式聚合分析。它的价值在于:确认某次短时爆发性等待是否真实存在、定位当时活跃的 client 程序和机器、交叉验证 alert.log 或 trace 中提到的会话行为。
怎么生成和获取有效的ASH dump文件
必须在故障发生中或刚结束时立刻执行,延迟超过 1 分钟就大概率失效——因为 v$active_session_history 默认仅驻留约 60–90 分钟内存数据,而 dump 是对当前 buffer 的一次性抓取。
- 用
oradebug在问题实例上触发:oradebug setmypid; oradebug dump ashdump 1(数字 1 表示 dump 当前所有 ASH buffer) - dump 输出路径由
user_dump_dest决定,典型位置如/u01/app/oracle/diag/rdbms/orcl/ORCL/trace/,文件名含ora_<pid>_ashdump.trc</pid> - 注意:该操作需
SYSDBA权限,且不能在 RAC 多节点同时 dump——每个节点要单独执行,否则会混入无关节点的采样
离线解析ASH dump需要哪些工具和前提
Oracle 官方不提供独立解析器,你得靠两个东西:一是 tkprof 的变通用法(仅能提取部分 wait event 统计),二是第三方脚本(如 ash-dump-parser.py,社区维护的 Python 工具,可从 GitHub 检索)。但无论哪种,都依赖一个关键前提:
- dump 文件必须完整,不能被截断——检查末尾是否有
*** DUMP END ***标记 - 必须知道生成该 dump 的数据库版本(比如 12.1.0.2),不同版本字段偏移不同,解析脚本需匹配
- 若 dump 中出现大量
sql_id = 0000000000000000或event = "NULL",说明 buffer 已被新采样覆盖,该 dump 实际已失真
常见误判:把ASH dump当AWR报告用
最典型的错误是拿 dump 文件去算“TOP SQL”或“平均等待时间”。它没有 time_waited 累计值,只有单次采样状态;也没有 blocking_session 链,无法追溯锁等待源头;更没有 plan_hash_value,没法关联执行计划变更。
如果你看到 dump 里有 200 行都写着 event = "SQL*Net message from client",这只能说明那几秒内至少有 200 个会话处于空闲等待,并不能推出连接池 maxActive 被打满——可能只是应用批量发请求后集体等响应,也可能只是网络抖动导致 ACK 延迟。真正判断池压,还得回溯应用日志或监控指标。
离线分析的核心价值,从来不是复现全貌,而是快速排除干扰、聚焦几个可疑会话 ID,再带着这些 ID 去翻对应时间点的 trace 文件或应用侧 thread dump。


















