Active Sessions持续偏高大概率是长期INACTIVE的“僵尸会话”未释放所致,它们不参与ASH采样(仅记录ON CPU/WAITING状态),需通过V$SESSION与LAST_CALL_ET交叉排查,并结合V$SESSION_CONNECT_INFO和网络层验证根因。
active sessions持续偏高,大概率不是真并发高,而是存在长期 inactive 却未释放的“僵尸会话”——它们不干活、不退出、占着 processes 配额,还可能拖慢连接池复用。ash本身不直接暴露这类会话,必须交叉查 v$session + v$active_session_history 才能揪出来。
查不到僵尸会话?因为ASH根本不采样INACTIVE状态
ASH只记录 session_state 为 'ON CPU' 或 'WAITING' 的前台会话,STATUS = 'INACTIVE' 的会话哪怕已挂12小时,也不会出现在 V$ACTIVE_SESSION_HISTORY 里。所以你翻遍ASH的 COUNT(*) GROUP BY SESSION_ID,永远看不到僵尸。
- 先确认真实连接数:执行
SELECT COUNT(*) FROM V$SESSION WHERE STATUS = 'INACTIVE' AND LAST_CALL_ET > 3600,筛选空闲超1小时的会话 - 再比对上限:查
SELECT VALUE FROM V$PARAMETER WHERE NAME = 'processes',若 INACTIVE 会话长期占满 60%+,基本可判定泄漏 - 别信
V$PROCESS的COUNT(*)—— 它包含后台进程,和客户端连接无关
怎么从ASH反向定位疑似僵尸的源头
僵尸会话虽不进ASH,但它们刚变 INACTIVE 前那一秒,可能被ASH捕获到异常行为。重点筛三类“退出前兆”样本:
-
EVENT = 'SQL*Net message from client'且SESSION_STATE = 'WAITING':说明应用发完请求就停住,没取结果,会话卡在等待客户端读走数据 -
SQL_ID IS NULL且PROGRAM LIKE '%jdbc%'或MODULE LIKE '%APP%':常见于Java应用未关闭Statement/ResultSet,连接归还池后仍残留会话 -
SAMPLE_TIME集中在某几分钟内爆发,之后该SESSION_ID再无任何ASH记录:典型“执行完就失联”,需立刻查对应时间点的V$SESSION状态
确认僵尸后,必须查客户端协议和网络层
只杀会话治标不治本。僵尸背后往往是应用端配置错误或代码缺陷,得拿到足够证据反馈给开发:
由 ReMe 驱动的记忆管理系统,支持跨会话记忆持久化、自动应用用户偏好以及智能上下文压缩...
- 用
V$SESSION_CONNECT_INFO查协议:执行SELECT SID, NETWORK_SERVICE_BANNER, CLIENT_CHARSET FROM V$SESSION_CONNECT_INFO WHERE SID IN (SELECT SID FROM V$SESSION WHERE STATUS = 'INACTIVE' AND LAST_CALL_ET > 3600) - 操作系统级验证:在DB服务器跑
netstat -an | grep :1521 | grep ESTABLISHED | wc -l,若远小于V$SESSION中的 INACTIVE 数,说明连接已断但Oracle未清理(常见于防火墙kill掉TCP但未发FIN) - 检查
V$SESSION的LOGON_TIME和LAST_CALL_ET差值:若差值极大(如登录3天、最后调用2小时),基本锁定为泄漏
真正难处理的不是“查得到”的僵尸,而是那些 STATUS = 'INACTIVE' 但 PROGRAM 显示为 oracle@host (J000) 的job进程残留——它们可能来自未清理的DBMS_JOB或过期的Scheduler job,得结合 DBA_SCHEDULER_JOBS 和 DBA_JOBS 对照查。










