Oracle

Oracle 間歇性拋出“ORA-12516,TNS:listener 找不到具有匹配協議棧的可用處理程序”

  • September 7, 2019

在測試 Oracle XE 連接建立機制時,我遇到了以下問題。儘管每次迭代都會關閉連接,但在 50-100 個連接之後,Oracle 開始間歇性地拋出以下異常:

java.sql.SQLException: Listener refused the connection with the following error:
ORA-12516, TNS:listener could not find available handler with matching protocol stack

   at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:489) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0]
   at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:553) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0]
   at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:254) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0]
   at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0]
   at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:528) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0]
   at oracle.jdbc.pool.OracleDataSource.getPhysicalConnection(OracleDataSource.java:280) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0]
   at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:207) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0]
   at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:157) ~[ojdbc6-11.2.0.4.jar:11.2.0.4.0]
   at com.vladmihalcea.book.high_performance_java_persistence.jdbc.connection.OracleConnectionCallTest.test(OracleConnectionCallTest.java:57) [test-classes/:na]

測試可以在 GitHub 上找到

for (int i = 0; i < callCount; i++) {
   try {
       long startNanos = System.nanoTime();
       try (Connection connection = dataSource.getConnection()) {
       }
       timer.update(System.nanoTime() - startNanos, TimeUnit.NANOSECONDS);
       sleep(waitMillis);
   } catch (SQLException e) {
       LOGGER.info("Exception on iteration " + i, e);
   }
}

如果我嘗試用 35 毫秒的等待步驟打開/關閉連接,一切正常。如果我將等待時間降低到 10 毫秒,異常就會開始不時拋出。

這篇文章可以解釋一個可能的原因:http ://www-01.ibm.com/support/docview.wss?uid=swg21603472

報告 TNS-12516 和/或 TNS-12519 錯誤的最常見原因之一是達到了配置的最大程序數和/或會話數限制。發生這種情況時,TNS 偵聽器的服務處理程序將變為“阻塞”並且無法建立新連接。一旦 TNS 偵聽器收到來自與數據庫實例關聯的 PMON 程序的更新,告訴 TNS 偵聽器門檻值低於配置的限制,並且數據庫現在正在接受連接連接恢復。

  • PMON 負責使用有關特定實例的資訊(例如負載和調度程序資訊)更新偵聽器。專用連接的最大負載由 PROCESSES 參數確定。PMON 提供 SERVICE_UPDATE 資訊的頻率根據實例的工作負載而有所不同。這些服務更新之間的最大間隔為 10 分鐘。
  • 偵聽器計算它與實例建立的連接數,但不會立即獲取有關已終止連接的資訊。只有當 PMON 通過 SERVICE_UPDATE 更新監聽器時,監聽器才會知道目前負載。由於這可能需要長達 10 分鐘,因此根據偵聽器的目前實例負載與實際實例負載之間可能存在差異。

當偵聽器認為目前連接數已達到最大負載時,它可能會將實例的服務處理程序的狀態設置為“阻塞”並開始拒絕傳入的客戶端連接,並出現以下錯誤之一:ora-12519 或 ora-1251 "

我想知道這是否是某種錯誤,或者僅僅是甲骨文的設計方式。

更新

在 Oracle 11g 企業版上,它工作得很好,所以這是一個 XE 限制。

使固定

使用連接池可能是解決此問題的最佳方法,它還可以減少連接獲取時間和升級流量峰值。

這不是一個錯誤。這種行為是預期的。如果您需要增加連接,只需更改程序限制:

SQL> show parameter processes
processes                            integer     150

SQL> alter system set processes = <integer> scope=[...];
SQL> shutdown immediate;
SQL> startup;

– 使用 pfile 或 spfile,您需要反彈 db,因為 processes 參數是靜態的。

為了完整起見,值得一提的是,在生產環境中,當您需要增加流程限制時,您可能還需要增加相關參數,例如事務和會話(源自流程)。您可以查詢 v$resource_limit 以確定目前使用的限制和值:

SQL> select * from v$resource_limit where resource_name in ('processes', 'sessions', 'transactions');

引用自:https://dba.stackexchange.com/questions/110819