如何处理连接到 Amazon RDS Oracle 实例时出现的“读取调用减1”错误

我在一个 Amazon RDS 实例上运行 Oracle 11GR2。偶尔我会收到一个 IO Error: Got minus one from a read call时,打电话给 DriverManager.getConnection(getUrl()),我不知道为什么。其他应用程序正常工作。

为了进一步混淆事情,错误会偶尔自我更正(在程序的下一次迭代之后)。

我应该如何处理“读取调用得到负1”错误?

完整堆栈跟踪:

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

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

其他信息:

  • 我认为这是一个糟糕的 JDBC URL,但它确实有用,有时候连续好几天才会失败。
  • AmazonRDS 是一个托管实例,配置更改可能是不可能的
  • 我使用 ojdbc6.jar 进行连接
332658 次浏览

The immediate cause of the problem is that the JDBC driver has attempted to read from a network Socket that has been closed by "the other end".

This could be due to a few things:

  • If the remote server has been configured (e.g. in the "SQLNET.ora" file) to not accept connections from your IP.

  • If the JDBC url is incorrect, you could be attempting to connect to something that isn't a database.

  • If there are too many open connections to the database service, it could refuse new connections.

Given the symptoms, I think the "too many connections" scenario is the most likely. That suggests that your application is leaking connections; i.e. creating connections and then failing to (always) close them.

I would like to augment to Stephen C's answer, my case was on the first dot. So since we have DHCP to allocate IP addresses in the company, DHCP changed my machine's address without of course asking neither me nor Oracle. So out of the blue oracle refused to do anything and gave the minus one dreaded exception. So if you want to workaround this once and for ever, and since TCP.INVITED_NODES of SQLNET.ora file does not accept wildcards as stated here, you can add you machine's hostname instead of the IP address.

We faced the same issue and fixed it. Below is the reason and solution.

Problem

When the connection pool mechanism is used, the application server (in our case, it is JBOSS) creates connections according to the min-connection parameter. If you have 10 applications running, and each has a min-connection of 10, then a total of 100 sessions will be created in the database. Also, in every database, there is a max-session parameter, if your total number of connections crosses that border, then you will get Got minus one from a read call.

FYI: Use the query below to see your total number of sessions:

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

Solution: With the help of our DBA, we increased that max-session parameter, so that all our application min-connection can accommodate.

I got this error message from using an oracle database in a docker despite the fact i had publish port to host option "-p 1521:1521". I was using jdbc url that was using ip address 127.0.0.1, i changed it to the host machine real ip address and everything worked then.

in my case, I got the same exception because the user that I configured in the app did not existed in the DB, creating the user and granting needed permissions solved the problem.

Cause

oracle binary permission issue ($ORACLE_HOME/bin/oracle)

[tst19c@exa033dbadm01 bin]$ $ORACLE_HOME/bin

[tst19c@exa033dbadm01 bin]$ ls -ltr oracle

-rwxr-s--x 1 tst19c asmadmin 446528768 May 3 14:28 oracle

Action Taken

[tst19c@exa033dbadm01 bin]$ chmod 6751 oracle

[tst19c@exa033dbadm01 bin]$ ls -ltr oracle

Now

-rwsr-s--x 1 tst19c asmadmin 446528768 May 3 14:28 oracle

[tst19c@exa033dbadm01 bin]$

I had a similar issue when running Oracle 21c XE image on Docker locally when I was trying to connect to it by localhost or 127.0.0.1.

The fix was to log in into the container and modify sqlnet.ora in the following way:

echo "DISABLE_OOB=ON" >> /opt/oracle/oradata/dbconfig/XE/sqlnet.ora

and restart the container.