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

Oracle 設定最大連接數後仍報 ORA-12518:Listener 同步延遲與連線洩漏分析

     編輯:Oracle 教學

Oracle 設定最大連接數後仍報 ORA-12518:Listener 同步延遲與連線洩漏分析

需更新 1,100 筆資料,已將 processes=1200、sessions=1325,但 Tomcat 仍報 ORA-12518。查詢 v$process 356、v$session 352,遠低於設定上限。根因有二:Listener 狀態同步延遲與應用端連線洩漏。

現象與環境

SQL> SHOW PARAMETER processes;
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
processes                            integer     1200

SQL> SELECT * FROM v$resource_limit;
RESOURCE_NAME      CURRENT_UTILIZATION  MAX_UTILIZATION  INITIAL_ALLOCATION  LIMIT_VALUE
------------------ -------------------  ---------------  ------------------  -----------
processes          24                   366              1200                1200
sessions           27                   362              1325                1325

當前使用僅 24 processes、27 sessions,歷史峰值 366/362,均未達上限。

核心原因:PMON 向 Listener 註冊間隔

  • PMON 預設每 60 秒 向 Listener 更新一次服務狀態(含當前連線數、負載)
  • Listener 依據此資訊決定是否轉交新連線
  • 若短時間內大量連線湧入,Listener 尚未收到最新狀態,仍認為負載已滿 → 拒絕轉交 → ORA-12518
  • 此時資料庫實際 Session 未滿,故不會報 ORA-00020

驗證查詢

-- 查看 PMON 註冊間隔(單位:秒)
SELECT value FROM v$parameter WHERE name = 'local_registration_address';
-- 或檢查 listener.ora 中的 SUBSCRIBE_FOR_NODE_DOWN_EVENT_ 設定

解決方案

  1. 修正應用程式連線洩漏(根本治本):
    • 所有 DB 操作務必在 finally 關閉 Connection/Statement/ResultSet
    • 使用連線池(HikariCP、Druid、DBCP2)並啟用 validationQuery、testOnBorrow
    • 設定合理的 maxActive、maxIdle、maxWait
  2. 調整 Listener 參數(治標):
    • listener.ora 加入 SUBSCRIBE_FOR_NODE_DOWN_EVENT_=OFF 減少註冊頻率干擾
    • 或設定 RATE_LIMIT 限制連線轉交速率
  3. 作業系統層面:
    • Linux: ulimit -n、/etc/security/limits.conf 調大檔案描述符上限
    • Windows: 注冊表 TcpTimedWaitDelay、MaxUserPort 優化 TIME_WAIT 回收

關鍵區別

錯誤代碼來源觸發條件典型場景
ORA-12518ListenerListener 認為無法轉交(負載滿、同步延遲、OS 限制)連線風暴、連線洩漏、PMON 同步延遲
ORA-00020Database實際 Session/Process 達上限真正連線耗盡、processes 設定過小

監控建議

-- 即時監控 Listener 負載
lsnrctl services
lsnrctl status

-- 即時監控 DB 連線
SELECT COUNT(*) FROM v$session;
SELECT COUNT(*) FROM v$process;
SELECT * FROM v$resource_limit WHERE resource_name IN ('processes','sessions');

結論:單純調大 processes/sessions 只解決資料庫端上限,無法解決 Listener 同步延遲與應用端洩漏。必須從應用程式碼、連線池、OS、Listener 多層面聯合治理。

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