logons current 持续高位不降且业务流量未增,基本可断定应用层存在连接泄露;表现为logons current台阶式跳升、logons cumulative小时增量异常放大、大量inactive会话logon_time高度集中,根源在于未调用connection.close()或连接池回收失效。
logons current 持续走高但没降下来,大概率是连接没关
oracle awr 报告里 logons current 是当前活跃会话数,它长期卡在高位(比如稳定在 200+),而业务流量没明显增长,基本可以断定应用层有连接泄露。这不是数据库负载高导致的正常现象,而是连接被打开后没调用 connection.close() 或没进连接池回收流程。
常见错误现象:Logons Current 曲线像台阶一样逐次跳升、不回落;同时 Logons Cumulative 的每小时增量异常放大(比如平时每小时增 500,突然变成 5000+)。
- 先确认是不是监控粒度问题:AWR 默认每小时拍一次快照,如果泄漏是突发短时行为,可能漏掉峰值,建议配合 ASH(
v$active_session_history)查最近 1 小时内LOGON_TIME集中在某个时间点的会话 - 别只盯 AWR Top Events:连接泄露本身不一定会触发“log file sync”或“enq: TX row lock”这类典型等待,反而常伴随大量空闲会话(
STATUS = 'INACTIVE'但LOGON_TIME是几小时前) - 检查
v$session时加条件TYPE = 'USER'和STATUS = 'INACTIVE',再按LOGON_TIME排序,看是否有一批会话登录时间高度一致且长时间未活动
Logons Cumulative 暴涨但 DB Time 没同步涨,说明连接开得勤、干得少
Logons Cumulative 是自实例启动以来总登录次数,它暴涨但 DB Time(数据库总服务时间)没同比例上升,说明大量连接建立后几乎没执行 SQL 就挂在那里——这是典型的“建连即闲置”,常见于连接池配置不当或 try-with-resources 缺失。
使用场景:某 Java 应用升级后 AWR 显示 Logons Cumulative 每 30 分钟涨 3000+,但平均并发执行 SQL 不到 5 个,SQL ordered by Gets 里也没新增高频小查询。
- 对比前后版本连接池配置:比如 HikariCP 的
maximumPoolSize没变,但connection-timeout从 30000 改成了 300,导致频繁建新连替代超时旧连 - 查
dba_hist_sqlstat中EXECUTIONS_DELTA总和,如果远小于Logons Cumulative增量,基本排除“真业务请求增多”,指向连接管理逻辑缺陷 - 注意 JDBC URL 是否误加了
?autoReconnect=true(MySQL 常见,Oracle 不支持,但有些驱动会静默忽略并反复重试建连)
用 AWR 找不到泄漏源头?直接查 v$session_longops 和 v$open_cursor
AWR 是汇总视图,细节不够。真要定位哪段代码或哪个模块在漏,得下钻到实时动态视图。重点不是看谁在跑长 SQL,而是看谁开着连却不干活。
性能影响:v$session 扫描代价低,但 v$open_cursor 在高并发下可能抖动,建议加 WHERE sid IN (SELECT sid FROM v$session WHERE status = 'INACTIVE' AND logon_time 缩小范围。
- 查异常长生命周期会话:
SELECT sid, serial#, username, logon_time, status, sql_id FROM v$session WHERE status = 'INACTIVE' AND last_call_et > 3600(空闲超 1 小时) - 查每个会话打开的游标数:
SELECT s.sid, s.username, c.count FROM v$session s, (SELECT sid, COUNT(*) count FROM v$open_cursor GROUP BY sid) c WHERE s.sid = c.sid AND c.count > 100,游标数远高于业务逻辑所需(比如一个简单查询通常 ≤ 5),往往意味着连接被复用但没清理语句资源 - 如果应用用了 Oracle UCP 或 WebLogic 连接池,务必查池的
LeakedConnectionCount监控项(不是 AWR 里的),它比数据库侧指标更直接
为什么 set unused column 不解决 Logons Current 高的问题
有人试过给用户表加 SET UNUSED 或杀会话脚本,发现 Logons Current 短暂下降又快速回升——因为泄漏源还在持续新建连接。这不是数据库对象或权限问题,是应用进程自己的资源管理失控。
容易踩的坑:以为重启监听器(lsnrctl reload)或清 tnsnames.ora 缓存能缓解,其实完全无关;还有人去调大 processes 参数,只是把 OOM 报错往后拖,掩盖了根本问题。
- 别依赖
ALTER SYSTEM KILL SESSION清理:临时有效,但泄漏代码没改,10 分钟后又回来;且频繁 kill 可能引发客户端重试风暴 - 确认应用日志里有没有 “Connection closed”、“Returned to pool” 类关键词,缺失这些日志大概率是没走标准关闭路径
- 最有效的验证方式:在测试环境用字节码增强工具(如 Byte Buddy)hook 所有
java.sql.Connection.close()调用,记录调用栈,立刻暴露哪行代码漏了
连接泄露的本质是应用层生命周期管理与数据库资源解耦失败,AWR 只负责报症状,根因永远在代码里那几个没被执行的 close() 调用上。










