v$active_session_history是唯一能捕获夜间批量卡死瞬间的实时视图,因其每秒采样活跃会话、内存保留约1小时数据,可精准定位会话、SQL、等待事件及阻塞链,而v$session仅反映当前状态、AWR快照间隔过长无法捕捉秒级卡顿。

夜间批量卡死时,别等天亮再查 AWR 报告——v$active_session_history 是唯一能抓住“卡死那几秒”的实时证据源,只要问题发生在最近 1 小时内,就能定位到具体会话、SQL、等待事件甚至阻塞源头。
为什么必须用 v$active_session_history 而不是 v$session 或 AWR
夜间批量作业一卡就是几分钟,但 v$session 只反映“当前”状态:等你连上去,卡住的会话可能已超时断开、或被监控脚本杀掉,只剩空壳;AWR 快照默认每小时一次,根本抓不到卡死瞬间。而 v$active_session_history 每秒采样一次活跃会话(非空闲),内存中保留最近约 60 分钟数据,是唯一能回溯“卡死发生时数据库到底在干什么”的视图。
- 采样不依赖会话是否还在线——即使会话已断开,它的历史样本仍在
- 字段包含
sql_id、event、blocking_session、session_state,可直接拼出等待链 - 不需提前开启任何开关,Oracle 默认启用(除非被显式禁用)
WHERE 条件漏一个就全白查
查 v$active_session_history 不是翻日志,必须用精准条件把噪音压下去,否则返回几万行毫无意义。核心过滤项缺一不可:
- 时间必须窄:
SAMPLE_TIME > SYSDATE - INTERVAL '10' MINUTE(卡死刚发生时用 5 分钟,持续卡用 10–15 分钟);别用SYSDATE - 1/24,NLS 设置偏差可能导致范围错位 - 只看真活跃会话:
session_state IN ('ON CPU', 'WAITING');排除INACTIVE和QUEUED等干扰项 - 夜间批量常见瓶颈集中在三类事件,直接筛:
event IN ('enq: TX - row lock contention', 'direct path write temp', 'db file sequential read') - RAC 环境必须用
gv$active_session_history,否则只看到本地节点,可能完全错过跨节点锁或 I/O 热点
如何一眼锁定卡死源头会话对
夜间批量常因两个作业互锁或一个作业疯狂争抢资源导致。不要靠肉眼扫表,用聚合快速聚焦:
- 先按
sql_id+event统计采样次数:COUNT(*)越高,说明该 SQL 在卡死时段越频繁处于该等待/CPU 状态 - 发现高频
sql_id后,立刻查它最近的阻塞关系:SELECT blocking_session, blocking_session_serial#, event FROM v$active_session_history WHERE sql_id = 'xxx' AND sample_time > SYSDATE - INTERVAL '5' MINUTE AND blocking_session IS NOT NULL - 若看到两个会话 A 和 B 在同一
SAMPLE_TIME下互相指向对方的blocking_session,且event都是enq: TX - row lock contention,就是死锁实锤,不用再猜 - 对
direct path write temp高频的 SQL,必须用DBMS_XPLAN.DISPLAY_CURSOR查执行计划,确认是否真有HASH JOIN或SORT ORDER BY步骤,且TempSpc列有预估值
容易被忽略的后台进程陷阱
业务连接全空、v$session 里几乎没活跃会话,但 OS CPU 还是 100%、I/O 也爆满?这时候重点查后台进程:
- 执行:
SELECT program, COUNT(*) FROM gv$active_session_history WHERE session_type = 'BACKGROUND' AND session_state = 'ON CPU' AND sample_time > SYSDATE - INTERVAL '5' MINUTE GROUP BY program ORDER BY 2 DESC - 高频
program值如ora_q000(AQ 监听)、cjq0(job 队列)、mmon(AWR 自动收集)往往意味着批量作业触发了隐式资源争抢,比如大量 job 并发执行、或 AWR 快照恰在批量高峰时启动 - 注意
sql_id = '0000000000000000'的样本,大概率是系统递归操作(如索引分裂、undo header 更新),得结合program和module往上追源头业务模块
ASH 数据是易失的,内存缓冲区默认 1 小时循环覆盖,RAC 下各节点独立缓冲——卡死一旦缓解,立刻查,别拖过夜。最危险的不是查不到,而是查了但条件松散、范围太宽,把真实信号淹没在噪声里。


















