ash视图查抖动窗口内活跃会话的等待事件、sql_id、会话状态等最有效,可精准定位短时性能尖峰的根因。
ash视图查什么数据最有效?
Oracle的ASH(Active Session History)本质是每秒采样一次活跃会话快照,它不记录空闲会话,只捕获正在执行SQL、等待事件或解析/硬解析中的会话。排查抖动时,重点不是看“平均负载”,而是找短时尖峰期间的会话分布和等待集中点。
- 优先查
V$ACTIVE_SESSION_HISTORY中SAMPLE_TIME在抖动窗口内(比如响应变慢那几十秒)的记录 - 关键字段:
EVENT(等待事件)、SQL_ID、SESSION_STATE、BLOCKING_SESSION、PROGRAM - 注意:默认只保留1小时ASH数据(受
_ash_disk_filter_ratio和磁盘空间影响),抖动发生后需尽快查,否则可能被覆盖
怎么定位抖动时刻的Top等待事件?
别直接跑全表统计,先用时间范围缩小。假设抖动发生在2024-05-20 14:22:10–14:22:40之间:
SELECT EVENT, COUNT(*) cnt FROM V$ACTIVE_SESSION_HISTORY WHERE SAMPLE_TIME BETWEEN TIMESTAMP '2024-05-20 14:22:10' AND TIMESTAMP '2024-05-20 14:22:40' GROUP BY EVENT ORDER BY cnt DESC;
- 如果看到大量
db file sequential read,说明单块读密集,可能是索引失效或小表全扫; - 出现高频
enq: TX - row lock contention,大概率有未提交事务阻塞了DML; -
library cache lock或cursor: pin S wait on X暗示SQL硬解析风暴,常因绑定变量缺失或cursor_sharing=EXACT且SQL文本微变导致; -
log file sync高占比?检查应用是否频繁COMMIT,或存储写延迟突增;
如何关联SQL_ID快速判断是不是某条SQL引发抖动?
ASH里SQL_ID为空不代表没SQL——可能是解析中(SESSION_STATE = 'PARSING')或PL/SQL执行(此时看PLSQL_ENTRY_OBJECT_ID)。实际排查要分层过滤:
- 先筛出抖动时段内非空
SQL_ID且SESSION_STATE = 'ON CPU'或等待事件非空的记录; - 对
SQL_ID按执行次数聚合,重点关注COUNT(*) > 5(即至少占5个采样点)的SQL; - 用
DBA_HIST_SQLTEXT或V$SQL查对应SQL文本,注意V$SQL可能已老化,优先查DBA_HIST_SQLTEXT(需AWR保留); - 若发现某
SQL_ID在抖动窗口内占了60%以上采样,且执行计划含FULL TABLE SCAN或NESTED LOOPS驱动大表,基本可锁定;
为什么ASH有时看不出抖动原因?常见盲区在哪?
ASH本身有固有限制,不是万能诊断入口:
- 采样间隔是1秒,
sub-second级抖动(如某次网络超时仅300ms)不会被捕获; - 如果抖动由后台进程引起(如
CKPT、DBWR卡住),而前台会话恰好处于空闲状态,ASH里就看不到对应活动; - RAC环境下,
GLOBAL CACHE CR BLOCK RECEIVE类等待可能分散在不同实例的ASH中,需合并查询GV$ACTIVE_SESSION_HISTORY; - 应用端连接池配置不当(如连接复用失败后重连风暴)可能表现为大量
SQL*Net message from client,但这属于正常等待,不能直接归因为数据库问题;
抖动分析真正的难点,往往不在ASH数据本身,而在于把ASH里的等待事件、SQL、时间戳和外部线索(如应用日志报错时间、监控系统GC暂停、存储IOPS突降)对齐——差1秒都可能错过关键证据。











