只查ash会漏掉已空闲但未断开的长连接,因其仅采样活动会话;需结合v$session中status='inactive'且last_call_et>1800的会话,并用logon_time确认真实连接时长。
ash 本身不直接暴露“长连接事务”的完整生命周期,必须和 v$session 的实时状态交叉验证才能准确定位——单独查 v$active_session_history 很容易漏掉已空闲但未断开的会话。
为什么只查 ASH 会错过真正的长连接
ASH 每秒采样一次,且只记录 正在活动(即非空闲、有等待或在 CPU 上执行)的会话。一旦事务提交、SQL 执行完毕、进入空闲状态,该会话就不再被采样,哪怕它还连着数据库、持有连接数配额、甚至锁着某些资源。
-
V$SESSION.STATUS = 'INACTIVE'且LAST_CALL_ET > 3600的会话,在 ASH 中几乎不会出现,但它可能已连了 2 小时、占着PROCESSES配额、甚至因未提交而锁住行 - ASH 的
SAMPLE_TIME是离散快照,无法反映会话从登录到当前的持续时间;V$SESSION.LOGON_TIME才是唯一可信的“连接起点” - 如果应用使用连接池且未正确 close(),这类会话常表现为
STATUS = 'INACTIVE'+MODULE固定(如'JDBC Thin Client')+CLIENT_IDENTIFIER为空或恒定
怎样用 V$SESSION 快速筛出可疑长连接
先锁定“活着但不动”的会话,再决定是否深入查 ASH 行为轨迹。执行以下查询可快速识别:
SELECT SID, SERIAL#, USERNAME, STATUS, LOGON_TIME, LAST_CALL_ET,
MODULE, CLIENT_IDENTIFIER, SQL_ID, EVENT
FROM V$SESSION
WHERE STATUS = 'INACTIVE'
AND LAST_CALL_ET > 1800 -- 空闲超30分钟
AND USERNAME IS NOT NULL
AND TYPE = 'USER';
-
LAST_CALL_ET是关键:单位为秒,表示“上一次调用结束至今的时间”,不是连接时长;但结合LOGON_TIME可算出真实连接时长:SYSDATE - LOGON_TIME - 排除
TYPE = 'BACKGROUND'和USERNAME IS NULL的后台进程,避免干扰 - 若
EVENT字段显示'SQL*Net message from client',基本确认是客户端没发新请求,连接悬空
什么时候该把 V$SESSION 结果关联进 ASH 查行为
仅当怀疑这些长连接“偶发活跃并拖慢系统”时,才用它们的 SESSION_ID 和 SESSION_SERIAL# 去翻 ASH,看历史有没有高耗时操作。例如:
SELECT SAMPLE_TIME, SQL_ID, EVENT, P1TEXT, P1, P2TEXT, P2, TIME_WAITED FROM V$ACTIVE_SESSION_HISTORY WHERE SESSION_ID = <sid> AND SESSION_SERIAL# = <serial> AND SAMPLE_TIME > SYSDATE - 1/24 -- 查最近1小时 ORDER BY SAMPLE_TIME DESC;</serial></sid>
- 不要用
COUNT(*) GROUP BY SQL_ID这类聚合——会掩盖单次执行耗时极长的问题 - 重点看
TIME_WAITED > 1000000(毫秒级,即超1秒)的采样点,这说明该会话某次操作确实卡住了 - 若
SQL_ID频繁出现且EVENT是'enq: TX - row lock contention',说明它虽空闲,但之前持锁未释放,仍在阻塞别人
容易被忽略的客户端线索:别只信 MACHINE 字段
V$SESSION.MACHINE 在共享服务器模式或代理连接下常失真(比如全显示为 'db-server'),不能当真实 IP 用。真正可用的字段组合是:
- 优先查
V$SESSION_CONNECT_INFO.CLIENT_ADDRESS:Oracle 11gR2+ 支持,含真实客户端 IP(需监听器配置VALID_NODE_CHECKING = NO或白名单) - 若应用层调用了
DBMS_SESSION.SET_IDENTIFIER('192.168.1.100'),则V$SESSION.CLIENT_IDENTIFIER可信 -
V$SESSION.PROGRAM和MODULE要结合看:比如PROGRAM = 'java@host123 (TNS V1-V3)'+MODULE = 'MyOrderService'比单看 MACHINE 更能定位服务实例
复杂点在于:一个长连接可能大部分时间在 V$SESSION 里“隐身”,只在某次执行慢 SQL 时短暂闪现在 ASH 中;所以监控必须双轨并行——V$SESSION 定连接存续,ASH 定行为异常,缺一不可。











