ASH不记录status字段,无法直接查INACTIVE会话;真正需关注的是在ASH中持续采样(如ON CPU或sql_id为0000000000000000)、关联v$transaction.used_ublk>10000且v$session.status='INACTIVE'的残留事务。

查 v$active_session_history 里 status 为 INACTIVE 但仍在采样中的会话
ASH 不记录会话状态(status 字段不存在),所以不能直接过滤 “INACTIVE”。真正要抓的是那些已断开连接、但事务未提交,仍在后台持有资源的会话——它们在 ASH 中表现为 session_state = 'ON CPU' 或空 event,且 sql_id 常为 0000000000000000 或系统递归语句,同时关联到 v$transaction.used_ublk > 10000。
关键动作不是看会话是否“活跃”,而是看它是否还在持续产生 ASH 样本:
- 运行
SELECT DISTINCT session_id, session_serial#, program, module FROM v$active_session_history WHERE sample_time > SYSDATE - 5/1440 AND sql_id IN ('0000000000000000', '0000000000000001') ORDER BY session_id; - 若返回的
program是oracle@host (J000)或oracle@host (CJQ0),基本就是 job 或 scheduler 启动的批处理残留事务 - 若
module显示为应用名(如MyApp-Batch)但近 5 分钟只出现 ON CPU 样本,说明应用已退出,但没发 COMMIT/ROLLBACK
用 v$transaction 和 v$session 反向验证 ASH 中疑似残留会话
ASH 只是快照,无法确认事务是否真实存在。必须立刻查 v$transaction 找出 used_ublk 高的事务,再通过 t.addr 关联 v$session 确认源头。
执行以下语句(注意:必须用 FETCH FIRST 限制结果,避免全表扫描):
SELECT s.sid, s.serial#, s.username, s.program, s.status, t.used_ublk, t.start_time FROM v$session s JOIN v$transaction t ON s.taddr = t.addr WHERE t.used_ublk > 10000 ORDER BY t.used_ublk DESC FETCH FIRST 5 ROWS ONLY;
重点关注:
-
status = 'INACTIVE':会话已断开,但事务仍开着,这是典型连接泄漏根源 -
username为空但program含(J000)或(CJQ0):DBMS_SCHEDULER 作业未提交 -
start_time距今超过 30 分钟:大概率是遗留事务,不是临时高峰
区分真 INACTIVE 连接泄漏和假性“堆积”
很多 DBA 看到大量 v$session.status = 'INACTIVE' 就以为是连接泄漏,其实多数是正常连接池行为。ASH 能帮你判断哪些是真问题:
- 如果这些 INACTIVE 会话在
v$active_session_history中完全无样本(即最近 1 小时没任何采样记录),说明它们只是空闲连接,不占 undo、不锁行、不消耗 PGA —— 不用管 - 如果它们在 ASH 中高频出现(比如每分钟都有
ON CPU样本),哪怕status是 INACTIVE,也代表背后有未结束事务在后台跑 -
v$session.last_call_et值极大(> 3600 秒)但v$transaction无对应记录 → 真空闲连接;若last_call_et小但v$transaction存在 → 应用逻辑 bug(比如异常退出前没 rollback)
为什么不能只依赖 dba_hist_active_sess_history 查 INACTIVE 占用
历史 ASH 表(dba_hist_active_sess_history)默认每 10 秒存一条,且归档时可能丢弃低频样本。一个已断开但未提交的会话,在内存中 v$active_session_history 里可能还有几十条样本,但在历史表里只剩 1–2 条甚至没有。
更麻烦的是:dba_hist_active_sess_history 的 session_id 和 session_serial# 在 RAC 环境下可能被重用,导致你查到的 “INACTIVE 会话” 实际是另一个早已结束的会话 ID。
所以定位这类问题,必须优先查 v$active_session_history(内存视图),再立即用 v$transaction 和 v$session 交叉验证。等 AWR 报告或历史表,往往黄花菜都凉了。











