簡體   English   中英

連接到 Amazon RDS Oracle 實例時如何處理“從讀取調用中得到減一”錯誤

[英]How to approach a "Got minus one from a read call" error when connecting to an Amazon RDS Oracle instance

我在 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 進行連接

問題的直接原因是 JDBC 驅動程序試圖從已被“另一端”關閉的網絡 Socket 中讀取數據。

這可能是由於以下幾點:

  • 如果遠程服務器已配置(例如在“SQLNET.ora”文件中)不接受來自您 IP 的連接。

  • 如果 JDBC url 不正確,您可能正在嘗試連接到不是數據庫的東西。

  • 如果與數據庫服務的打開連接過多,它可能會拒絕新連接。

鑒於這些症狀,我認為“連接過多”的情況最有可能。 這表明您的應用程序正在泄漏連接; 即創建連接,然后未能(總是)關閉它們。

我們遇到了同樣的問題並修復了它。 下面是原因和解決方法。

問題

當使用連接池機制時,應用服務器(在我們的例子中是 JBOSS)根據min-connection參數創建連接。 如果您有 10 個應用程序在運行,並且每個應用程序的min-connection為 10,那么將在數據庫中創建總共 100 個會話。 此外,在每個數據庫中,都有一個max-session參數,如果您的連接總數越過該邊界,那么您將從Got minus one from a read call得到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都可以容納。

盡管我已將端口發布到主機選項“-p 1521:1521”,但我還是通過在 docker 中使用 oracle 數據庫收到此錯誤消息。 我使用的是使用 ip 地址 127.0.0.1 的 jdbc url,我將其更改為主機真實 ip 地址,然后一切正常。

我想補充斯蒂芬 C 的回答,我的情況在第一個點上。 所以既然我們有DHCP來分配公司的IP地址,DHCP就改變了我機器的地址,當然既不問我也不問Oracle。 因此,出乎意料的 oracle 拒絕做任何事情,並給出了一個可怕的例外。 因此,如果您想一勞永逸地解決此問題,並且由於 SQLNET.ora 文件的 TCP.INVITED_NODES 不接受此處所述的通配符,您可以添加您機器的主機名而不是 IP 地址。

就我而言,我遇到了同樣的異常,因為我在應用程序中配置的用戶在數據庫中不存在,創建用戶並授予所需的權限解決了問題。

原因

oracle 二進制權限問題 ($ORACLE_HOME/bin/oracle)

[tst19c@exa033dbadm01 bin]$ $ORACLE_HOME/bin

[tst19c@exa033dbadm01 bin]$ ls -ltr oracle

-rwxr-s--x 1 tst19c asmadmin 446528768 5 月 3 日 14:28 oracle

所采取的行動

[tst19c@exa033dbadm01 bin]$ chmod 6751 oracle

[tst19c@exa033dbadm01 bin]$ ls -ltr oracle

現在

-rwsr-s--x 1 tst19c asmadmin 446528768 5 月 3 日 14:28 oracle

[tst19c@exa033dbadm01 bin]$

當我嘗試通過localhost127.0.0.1本地Docker 上運行Oracle 21c XE映像時,我遇到了類似的問題。

修復方法是登錄容器並按以下方式修改sqlnet.ora

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

並重新啟動容器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM