连接到Amazon RDS Oracle实例时如何解决“读取调用中减去一个”错误


67

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

为了进一步混淆,错误有时会自动纠正(在程序的下一次迭代之后)。

我应该如何处理“从读取呼叫中减去一个”错误?

全栈跟踪:

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进行连接

还请考虑以下问题: stackoverflow.com/questions/31704622可能不推荐使用您正在使用的OracleDriver。
劳尔·卢纳

Answers:


95

问题的直接原因是JDBC驱动程序试图从被“另一端”关闭的网络套接字中读取。

这可能是由于以下原因:

  • 如果已将远程服务器配置为(例如,在“ SQLNET.ora”文件中)不接受来自IP的连接。

  • 如果JDBC网址不正确,则您可能正在尝试连接到非数据库对象。

  • 如果到数据库服务的打开的连接太多,它可能会拒绝新的连接。

考虑到这些症状,我认为最有可能出现“连接过多”的情况。这表明您的应用程序正在泄漏连接。即创建连接,然后无法(始终)关闭它们。


1
关闭任何干预网络连接的代理或VPN软件也可以解决此问题。
Patzu

好吧 重新启动客户端或AWS实例也会如此。但是这些都是创可贴。他们没有解决根本的问题。
Stephen C

15

我们面临同样的问题,并已解决。下面是原因和解决方法。

问题

使用连接池机制时,应用程序服务器(在我们的示例中为JBOSS)根据该min-connection参数创建连接。如果您有10个应用程序在运行,而每个应用程序有10min-connection个,则将在数据库中创建总共100个会话。另外,在每个数据库中,都有一个max-session参数,如果您的连接总数越过边界,那么您将得到Got minus one from a read call

仅供参考:使用以下查询查看您的会话总数:

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

解决方案:在DBA的帮助下,我们增加了该max-session参数,以便我们所有的应用程序min-connection都可以容纳。


如果超过MAXPROCESS或MAXSESSION,则确实会遇到特定于该情况的ORA-错误,连接并不会简单地关闭。
eckes

1

我想补充一下斯蒂芬·C的回答,我的案子在第一点。因此,由于我们有DHCP在公司中分配IP地址,因此DHCP更改了我机器的地址,而没有问我也没有Oracle。因此,甲骨文突然拒绝执行任何操作,并给减号一个可怕的例外。因此,如果您想一劳永逸地解决此问题,并且由于SQLNET.ora文件的TCP.INVITED_NODES不接受此处所述的通配符,则可以添加计算机的主机名而不是IP地址。


这就是为什么我们为服务器使用静态IP。或者,如果要使用DHCP,则可以通过DHCP保留为MAC地址分配特定的IP。
太阳

@Sun我的电脑是服务器。
Stelios Adamantidis,2016年

1
是的,如果您无法控制IP供应...您可以做的不多,但希望主机名能跟上IP地址的更改。
太阳

1

尽管我已将端口发布到主机选项“ -p 1521:1521”,但我在docker中使用oracle数据库却收到此错误消息。我正在使用使用IP地址127.0.0.1的jdbc url,我将其更改为主机的真实IP地址,然后一切正常。


0

就我而言,我遇到了同样的异常,因为在数据库中不存在我在应用程序中配置的用户,创建该用户并授予所需的权限可以解决该问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.