web-dev-qa-db-ja.com

Amazon RDS Oracleインスタンスに接続するときに「読み取り呼び出しから1つを引いた」エラーにアプローチする方法

Amazon RDSインスタンスでOracle 11GR2を実行しています。時折、DriverManager.getConnection(getUrl())を呼び出すときにIO Error: Got minus one from a read callを受け取りますが、その理由はわかりません。他のアプリケーションは正常に動作します。

さらに混乱させるために、エラーは時々修正されます(プログラムの次の反復後)。

「Got-read read from one」のエラーにどのようにアプローチすればよいですか?

完全なスタックトレース:

Java.sql.SQLRecoverableException: IO Error: Got minus one from a read call
    at Oracle.jdbc.driver.T4CConnection.logon(T4CConnection.Java:489)
    at Oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.Java:553)
    at Oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.Java:254)
    at Oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.Java:32)
    at Oracle.jdbc.driver.OracleDriver.connect(OracleDriver.Java:528)
    at Java.sql.DriverManager.getConnection(DriverManager.Java:579)
    at Java.sql.DriverManager.getConnection(DriverManager.Java:243)
    at com.cwd.facile.db.Database.<init>(Database.Java:44)
    at com.cwd.facile.ns.NetSuiteRequestBased.<init>(NetSuiteRequestBased.Java:29)
    at com.cwd.facile.ns.CommonOperations.isInventoryItem(CommonOperations.Java:205)
    at com.cwd.facile.ns.CommonOperations.findItemIdByName(CommonOperations.Java:188)
    at com.cwd.facile.ns.CommonOperations.createSalesOrder(CommonOperations.Java:970)
    at com.cwd.facile.Main.main(Main.Java:47)
Caused by: Oracle.net.ns.NetException: Got minus one from a read call
    at Oracle.net.ns.Packet.receive(Packet.Java:311)
    at Oracle.net.ns.NSProtocol.connect(NSProtocol.Java:300)
    at Oracle.jdbc.driver.T4CConnection.connect(T4CConnection.Java:1140)
    at Oracle.jdbc.driver.T4CConnection.logon(T4CConnection.Java:340)
    ... 12 more

Database.Java行44:setConn(DriverManager.getConnection(getUrl()));

他の情報:

  • 私はそれが悪いJDBC URLだと思っていましたが、機能することもあり、失敗するまで何日も続きました。
  • Amazon RDSはマネージドインスタンスであり、構成を変更できない場合があります
  • 接続にojdbc6.jarを使用しています
55
Robert H

この問題の直接的な原因は、JDBCドライバーが「もう一方の端」によって閉じられたネットワークソケットから読み取ろうとしたことです。

これはいくつかの原因による可能性があります。

  • IPからの接続を受け入れないようにリモートサーバーが構成されている場合(「SQLNET.ora」ファイルなど)。

  • JDBC URLが正しくない場合、データベースではないものに接続しようとしている可能性があります。

  • データベースサービスへの開いている接続が多すぎる場合、新しい接続を拒否する可能性があります。

症状を考えると、「接続が多すぎる」シナリオが最も可能性が高いと思います。これは、アプリケーションが接続をリークしていることを示しています。つまり、接続を作成してから、(常に)接続に失敗します。

77
Stephen C

同じ問題に直面し、修正しました。以下が理由と解決策です。

問題

接続プールメカニズムを介してデータベース接続を作成すると、アプリサーバー(この場合はJBOSS)がmin-connectionパラメーターで述べたように接続を作成します。 10個のアプリケーションを実行していて、それぞれのアプリケーションのmin接続が10である場合、合計100個のセッションがデータベースに作成されます。また、すべてのデータベースにmax-sessionパラメーターがあります。合計接続がその境界を超えると、「読み取り呼び出しから1を引いた」というメッセージが表示されます。

SELECT username, count(username) FROM v$session 
WHERE username IS NOT NULL group by username

解決策:DBAの助けを借りて、すべてのアプリケーションの最小接続に対応できるように、その最大セッションを増やしました。

10
Arnab Sarkar

私はスティーブンCの答えを補強したいと思います。私の場合は最初の点についてでした。したがって、社内にIPアドレスを割り当てるDHCPがあるため、DHCPはもちろん、私にもOracleにも尋ねることなく、マシンのアドレスを変更しました。だから、オラクルは何もすることを拒否し、マイナス1の恐ろしい例外を与えました。したがって、これを永遠に回避したい場合、およびSQLNET.oraファイルのTCP.INVITED_NODESが here のようにワイルドカードを受け入れないため、IPアドレスの代わりにマシンのホスト名を追加できます。

1