首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle 找出佔用連線的 SQL:v$session 實戰排查連線洩漏

     編輯:Oracle 資料庫基礎

應用程式未正確關閉資料庫連線,導致連線池耗盡、系統癱瘓是常見事故。本文提供一條實戰 SQL,快速鎖定特定應用伺服器(如 WebLogic)正在執行的 SQL 文字,協助開發人員定位洩漏程式碼。

問題情境

  • 應用伺服器(如 WLS254)連線數持續攀升,最終觸發 ORA-12519 或 ORA-00018。
  • 程式碼量大,難以靜態審查哪段邏輯漏掉 close() 或 returnConnection()。

核心查詢 SQL

SELECT sql_text
FROM v$sqlarea a
WHERE a.HASH_VALUE IN (
  SELECT b.prev_hash_value
  FROM v$session b
  WHERE b.MACHINE = 'WLS254'  -- 替換為你的應用伺服器主機名
);

原理解析

  1. v$session 記錄每個當前連線的狀態,MACHINE 欄位可辨識發起連線的客戶端主機。
  2. prev_hash_value 指向該 session 最近執行的 SQL 在 v$sqlarea 的雜湊值。
  3. 透過 HASH_VALUE 關聯 v$sqlarea 即可取得完整 sql_text。

v$session 關鍵欄位速查表

欄位說明
SID / SERIAL#Session 唯一識別碼,ALTER SYSTEM KILL SESSION 'sid,serial#' 時使用
MACHINE客戶端主機名稱,定位應用伺服器關鍵
PROGRAM客戶端程式名稱(如 java.exe、w3wp.exe)
OSUSER作業系統登入帳號
STATUSACTIVE 執行中、INACTIVE 閒置、KILLED 已標記終止
SQL_HASH_VALUE / SQL_ADDRESS當前/最近執行 SQL 的雜湊值與記憶體位址
MODULE / ACTION經 DBMS_APPLICATION_INFO.SET_MODULE/ACTION 設定,便於追蹤業務流程
LOGON_TIME連線建立時間,判斷長連線
LAST_CALL_ET最後一次呼叫經過秒數,判斷閒置過久

進階排查:找出長時間閒置但未釋放的連線

SELECT s.sid, s.serial#, s.machine, s.program, s.osuser,
       s.logon_time, s.last_call_et,
       sq.sql_text
FROM v$session s
LEFT JOIN v$sqlarea sq ON s.sql_hash_value = sq.hash_value
WHERE s.machine = 'WLS254'
  AND s.status = 'INACTIVE'
  AND s.last_call_et > 3600  -- 閒置超過 1 小時
ORDER BY s.last_call_et DESC;

開發端修正清單

  • 所有取得連線的程式碼必須在 finally 區塊或 try-with-resources 中關閉。
  • 連線池設定 idleTimeout、maxLifetime,強制回收閒置連線。
  • 啟用 v$session 監控腳本,定期巡檢連線數與執行 SQL。
  • 在關鍵業務流程埋點 DBMS_APPLICATION_INFO.SET_MODULE('模組名','動作名'),方便事後追蹤。

掌握這套查詢技巧,即可在幾分鐘內從數百條連線中精準找出「那條忘記關閉的 SQL」,快速止血並導向程式碼修正。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved