如何通过plsql developer判断程序是否有未释放连接(简易版)

如何判断程序是否有未释放连接

【案例】程序连接未释放,导致数据库连接不断累积,最终Tomcat报连接数不足

 

锁的问题,参考:

【附1】怎么查事务阻塞

【附2】怎么查干完事情没提交

 

程序连接未释放排查

【案例】程序连接未释放,导致数据库连接不断累积,最终Tomcat报连接数不足

STEP1: pl/sql developer的“工具”->“会话”里选择“Prev exec start”并点三角号排序

 

 

  这些会话是早上的,它空闲超时时间已经超过Tomcat里的设置,而且Tomcat里设置的空闲会话是15个,这里累积有上百条记录未释放,执行的最后一条SQLPrev_sql_id)都一样,都是bnmpw635kv4k1

 

推测是SQL卡住或者跑完了未结束会话啥都不干。这里还只是推测,继续往下。

我们至少要确认它的来源是否是我们的Tomcat程序

 

STEP2: 拉动上屏幕,查看这条对应的状态

 

状态为INACTIVE”说明它确实跑完了,而不是被锁阻塞或者性能太差跑不完(后两者都是运行中,都是ACTIVE”才对),疑似未释放连接。那么他是由那台服务器那个()程序发起的,看右侧就知道了,JDBC就是我们的Tomcat程序发起的。

这里可排除SQL一直跑不完或者被阻塞的猜测,确认是跑完这条SQL后在那边占着连接池会话什么都没干,继续往下。

 

STEP3: 回到第一张图,它对应的SQL全文可以通过游标页面找到(或者select sql_fulltext from gv$sql where sql_id=’bnmpw635kv4k1’),注意“游标”页面的最右侧Cursor”显示为“OPEN也明确了这条执行完后,还在内存里占着坑。

 

STEP4: 根据观察,会话数是不断累积,没释放导致最后连接池满掉。回到第一张图,发现这些会话的时间,大约间隔10分钟调用一次(两节点RAC可能会是5分钟),呈现规律性,疑似定时器之类的程序发起,查定时器确认问题点。

锁的问题

【附1】查锁阻塞的SQL

SELECT    bs.username "DB User",

          bs.SID "SID",bs.serial# "Serial#",

          bs.machine "Blocking Machine",bs.program "Blocking App",

          ws.SID "WSID",ws.serial# "WSerial#",

          ws.machine "Waiting Machine",ws.program "Waiting App"

               FROM gv$lock hk, gv$session bs, gv$lock wk, gv$session ws

    WHERE hk.BLOCK = 1

      AND hk.lmode != 0

      AND hk.lmode != 1

      AND wk.request != 0

      AND wk.TYPE(+) = hk.TYPE

      AND wk.id1(+) = hk.id1

      AND wk.id2(+) = hk.id2

      AND hk.SID = bs.SID(+)

      AND wk.SID = ws.SID(+)

      AND (bs.username IS NOT NULL)

      AND (bs.username <> 'SYSTEM')

      AND (bs.username <> 'SYS')

      AND wk.ctime>1

ORDER BY 1;

 

 

查出结果的红色方框的机器和程序堵了蓝色方框的,通过红色方框的SID(如204)到“会话”->“工具”的“SQL文本”,可找出SQL

 

【附2】查未提交SQL

select /*+ rule */ o.owner as 所有者,o.object_name as 对象名称,

       s.sid,

       s.serial#,

       s.machine,

       case

         when s.sql_id is null then

          'SQL未提交等待'

         else

          'SQL执行等待'

       end as 等待类型,

       q.sql_fulltext as 正在执行的SQL,

       nvl(s.sql_id, s.prev_sql_id) sql_id

  from gv$locked_object l,

       dba_objects     o,

       gv$session       s,

       gv$sql       q

 where l.object_id = o.object_id

   and l.session_id = s.sid and o.owner NOT IN ('SYSTEM','SYS','SYSMAN') and round(s.wait_time_micro/1000000)>=10 /* 超过10秒未提交或被阻塞超过10*/

   and nvl(s.sql_id, s.prev_sql_id) = q.sql_id

 order by s.sid, sql_id;

 

 

“等待类型”是“SQL未提交等待”,就要注意是否有事务做完了没提交结束

 

posted @   17岁奋青  阅读(555)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示