必须立刻查gv$active_session_history且时间窗口不超5分钟,因ASH内存仅保留约1小时、高负载下更短,写死时间或用BETWEEN易漏样本;需用SYSDATE-INTERVAL'5'MINUTE动态计算,避免NLS时区解析失败及采样点间隙遗漏。

必须立刻查 gv$active_session_history,且时间窗口不能宽于 5 分钟——ASH 内存只保留约 1 小时,高负载下可能只剩十几分钟,写死时间或用 BETWEEN 极易漏掉关键样本。
为什么刚发生的抖动在 ASH 里查不到
常见现象是执行 SELECT * FROM v$active_session_history WHERE sample_time > '2026-09-17 20:30:00' 返回空,不是没发生,而是踩中了三个坑:
-
v$active_session_history是内存视图,采样非连续(每秒约 1 次),且受 SGA 压力影响会提前滚动覆盖;RAC 环境下若只查v$不查gv$,默认只返回当前节点数据,抖动若发生在 node3,你在 node1 上永远看不到 - 写死时间字符串(如
'2026-09-17 20:30:00')受会话NLS_DATE_FORMAT和时区影响,极易解析失败或范围偏移 - 用
SAMPLE_TIME BETWEEN t1 AND t2会卡死边界,而抖动常发生在两个采样点之间(比如问题在 20:32:27.8,但最近采样是 20:32:27.0 和 20:32:28.0),直接错过
正确做法是:SAMPLE_TIME > SYSDATE - INTERVAL '5' MINUTE,它动态计算、不受时区干扰、覆盖足够抖动窗口。
怎么快速锁定抖动时刻和主因事件
别扫全量字段,聚焦三类信号组合:时间 + 状态 + 事件。抖动本质是资源争用或等待堆积,ASH 里最敏感的线索是密集出现的 WAITING 或异常长的 ON CPU 样本。
- 先看是否真卡在 I/O:执行
SELECT sql_id, event, COUNT(*) FROM gv$active_session_history WHERE session_state = 'WAITING' AND event IN ('db file sequential read', 'db file scattered read', 'log file sync', 'direct path write temp') AND sample_time > SYSDATE - INTERVAL '3' MINUTE GROUP BY sql_id, event HAVING COUNT(*) >= 3 ORDER BY COUNT(*) DESC。连续 ≥3 秒同一sql_id+event高频出现,基本可定位为存储层或日志同步抖动 - 再看是否真在狂算:执行
SELECT sql_id, COUNT(*) FROM gv$active_session_history WHERE session_state = 'ON CPU' AND sample_time > SYSDATE - INTERVAL '5' MINUTE GROUP BY sql_id ORDER BY COUNT(*) DESC FETCH FIRST 5 ROWS ONLY。若某sql_id样本数远超其他(比如 80+ vs 其他 - 最后交叉验证阻塞链:对上述高样本
sql_id,追加blocking_session和final_blocking_instance字段,查是否跨节点锁冲突。RAC 下enq: TX - row lock contention出现在多个实例且final_blocking_instance指向另一节点,就是典型跨节点锁抖动
查到 SQL_ID 后文本丢失怎么办
v$active_session_history 只存 sql_id,不存文本。生产环境里,高频抖动 SQL 往往已老化出共享池,v$sql 查不到是常态。
- 优先查
DBA_HIST_SQLTEXT:它从 AWR 快照固化,只要该 SQL 近期进过快照(默认 60 分钟一次),大概率还在。语句:SELECT sql_text FROM DBA_HIST_SQLTEXT WHERE sql_id = 'xxx' AND ROWNUM = 1 - 若
DBA_HIST_SQLTEXT也空,说明该 SQL 执行极短、未被 AWR 捕获,此时必须结合PLAN_HASH_VALUE和执行计划反推。用DBMS_XPLAN.DISPLAY_CURSOR('xxx', NULL, 'outline +peeked_binds')看当前游标计划,重点确认是否有SORT AGGREGATE、HASH JOIN或TEMP TABLE TRANSFORMATION——这些物理操作节点才是触发抖动的直接原因 - 切忌靠
v$sort_usage.sql_id定位临时表空间问题,它不可靠。该视图的sql_id来自v$session.prev_sql_id,只要会话执行新语句,旧临时段就“断连”,你看到的可能是上一条早已结束的 SQL
为什么不能只依赖 AWR 报告
AWR 是快照聚合,最小粒度 10–60 分钟,而真实抖动常发生在秒级。比如用户反馈“7:42:15–7:42:18 卡死”,AWR 快照 #1234(7:40–7:50)里 DB Time 可能只显示均值升高,看不出峰值;Top Events 里 log file sync 平均等待 5ms,掩盖了那三秒内突增至 200ms 的尖刺。
CHM 能补这个缺口,但它只采集 OS 层指标;ASH 是唯一同时带数据库上下文(sql_id、current_obj#、blocking_session)和秒级精度的证据源。真正要抓“哪一秒、哪个会话、哪条 SQL、在等什么、被谁卡”,必须用 gv$active_session_history,且时间条件必须够窄、够活、够 RAC-aware。



















