Oracle 11g: JDBC作业中止,并出现 "IO Error: 连接重置"。

问题描述 投票:0回答:1

我想弄清楚为什么我们的Oracle 11g会出现错误行为。我们在所有使用JDBC访问数据库的作业中都出现了以下错误。

Error message: java.sql.SQLRecoverableException: IO Error: Connection reset

在大家不高兴之前,是的,我已经检查了堆栈溢出上的其他相关链接(天知道还有多少其他网站)。到目前为止没有任何帮助,我想知道下一步我可以尝试什么。

在过去的几个月里,情况已经恶化了,唯一改变的是访问数据库的作业是在docker容器中运行的。唯一受影响的数据库是oracle 11g(我们还有其他几个数据库,包括oracle 12c)。我可以使用sqlplus顺利访问11g数据库。

由于这是一个连接的问题,我自然检查了以下文件。tnsnames.oralistener.ora. 以下是它们所包含的内容(相关数据库的SID=TMF).tnsnames.ora。

GLOB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = linuxoracle11)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = GLOB)
    )
  )

STATIC =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = linuxoracle11)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = STATIC)
    )
  )

TMF =
  (DESCRIPTION =
    (SDU=2048)
    (TDU=2048)
    (ADDRESS = (PROTOCOL = TCP)(HOST = linuxoracle11)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = SHARED)
      (SERVICE_NAME = TMF)
    )
  )

DEMO =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = linuxoracle11)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = DEMO)
    )
  )

HONDADB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = linuxoracle11)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = HONDADB)
    )
  )

TEMP =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = linuxoracle11)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = TEMP)
    )
  )

EXTPROC_CONNECTION_DATA =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
    )
    (CONNECT_DATA =
      (SID = PLSExtProc)
      (PRESENTATION = RO)
    )
  )

listener.ora:

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = TMF)
      (ORACLE_HOME = /home/oracle/app/oracle/product/11.2.0/dbhome_1)
      (SID_NAME = TMF)
    )

    (SID_DESC =
      (GLOBAL_DBNAME = STATIC)
      (ORACLE_HOME = /home/oracle/app/oracle/product/11.2.0/dbhome_1)
      (SID_NAME = STATIC)
    )

    (SID_DESC =
      (GLOBAL_DBNAME = DEMO)
      (ORACLE_HOME = /home/oracle/app/oracle/product/11.2.0/dbhome_1)
      (SID_NAME = DEMO)
    )
  )


LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = linuxoracle11)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
  )

我实在看不出哪里出了问题。监听者跟踪日志有大量这样的条目。

09-JUN-2020 18:25:21 * service_died * TMF * 12537
09-JUN-2020 18:25:22 * service_register * TMF * 0
09-JUN-2020 18:25:27 * service_died * TMF * 12537
09-JUN-2020 18:25:28 * service_register * TMF * 0
Tue Jun 09 18:25:33 2020
09-JUN-2020 18:25:33 * service_died * TMF * 12537
09-JUN-2020 18:25:34 * service_register * TMF * 0
09-JUN-2020 18:25:39 * service_died * TMF * 12537
09-JUN-2020 18:25:40 * service_register * TMF * 0
Tue Jun 09 18:25:45 2020
09-JUN-2020 18:25:45 * service_died * TMF * 12537
09-JUN-2020 18:25:46 * service_register * TMF * 0
09-JUN-2020 18:25:51 * service_died * TMF * 12537
09-JUN-2020 18:25:52 * service_register * TMF * 0
Tue Jun 09 18:25:57 2020
09-JUN-2020 18:25:57 * service_died * TMF * 12537
09-JUN-2020 18:25:58 * service_register * TMF * 0
09-JUN-2020 18:26:03 * service_died * TMF * 12537
09-JUN-2020 18:26:04 * service_register * TMF * 0

我最近尝试修复这个问题的方法是对这个信息做了些许修改: 甲骨文社区岗位. 服务器上的设置。

[root@linuxoracle11 trace]# mv /dev/random /dev/xrandom
[root@linuxoracle11 trace]# ln -s /dev/urandom /dev/random
[root@linuxoracle11 trace]# ls -l /dev/*ndom
lrwxrwxrwx 1 root root   12 Jun  9 19:26 /dev/random -> /dev/urandom
crw-rw-rw- 1 root root 1, 9 Jun  9 09:58 /dev/urandom
crw-rw-rw- 1 root root 1, 8 Jun  9 09:58 /dev/xrandom

然而,这并没有解决这个问题,对着数据库运行的作业仍然在中止。

最令人恼火的是 有时 的工作运行通过无错误。我将会感激f任何人有一个提示,我应该在哪个方向寻找。

编辑:按照要求,这里是sqlnet.ora文件的内容。

SQLNET.RECV_TIMEOUT=5
SQLNET.INBOUND_CONNECT_TIMEOUT=5

是的,那是数据库系统安装时产生的默认值。

还有人说可能是由于 "登录风暴 "造成的。这点值得怀疑,因为我们数据库的实际用户很少。主要是我写的那些在docker容器中运行的作业。我检查了oracle doco和一些信息(同样来自Burleson咨询公司的页面),并尝试了以下内容。

SQL> select resource_name, current_utilization, limit_value
  2  from v_$resource_limit
  3  where resource_name in ('processes', 'sessions');

RESOURCE_NAME                  CURRENT_UTILIZATION LIMIT_VALU
------------------------------ ------------------- ----------
processes                      25                  200
sessions                       30                  322

所以我们说的是几十个连接,而不是几百个。

编辑2: 为了完整起见,这里是堆栈跟踪的一部分。

****** Jun 12, 2020 9:20:32 PM IO Error: Connection reset ******
java.sql.SQLRecoverableException: IO Error: Connection reset
    at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:752)
    at oracle.jdbc.driver.PhysicalConnection.connect(PhysicalConnection.java:666)
    at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
    at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:566)
    at java.sql.DriverManager.getConnection(DriverManager.java:664)
    at java.sql.DriverManager.getConnection(DriverManager.java:247)
...

Caused by: java.net.SocketException: Connection reset
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:115)
    at java.net.SocketOutputStream.write(SocketOutputStream.java:155)
    at oracle.net.ns.DataPacket.send(DataPacket.java:209)
    at oracle.net.ns.NetOutputStream.flush(NetOutputStream.java:215)
    at oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:302)
    at oracle.net.ns.NetInputStream.read(NetInputStream.java:249)
    at oracle.net.ns.NetInputStream.read(NetInputStream.java:171)
    at oracle.net.ns.NetInputStream.read(NetInputStream.java:89)
    at oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:123)
    at oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:79)
    at oracle.jdbc.driver.T4CMAREngineStream.unmarshalUB1(T4CMAREngineStream.java:429)
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:397)
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:257)
    at oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:437)
    at oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:954)
    at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:639)
    ... 38 more
oracle jdbc
1个回答
0
投票

你应该提供完整的堆栈跟踪,当堆栈跟踪包含以下内容时。

在oracle.jdbc.driver.T4CConnection.logon的时候

然后连接被数据库重置了,在认证过程中。(不是被任何网络设备在途中).出现这种情况(登录风暴)的根本原因问题其实是客户端的问题。由于缺乏随机数,客户端无法快速认证自己。当这种情况发生时,那么你可以。

  • 调整内核参数,在缓冲区(客户端)中存放更多的随机数。
  • 使用JVM使用另一个dev*random设备(客户端)的技巧
  • 修改SQLNET.INBOUND_CONNECT_TIMEOUT参数,延长服务器等待客户端(db服务器)的时间窗口。

但也有可能是其他原因导致你收到这个错误。

PS:JVM对第2个 "解决方案 "有明确的保护措施(Java bug 6202721)。因为它会影响安全性。所以如果你设置 "java.security.egd=file:devurandom",它会故意忽略你。虽然这个设备名不是黑名单 "java.security.egd=file:dev.urandom"


0
投票

这里是 sqlnet.ora 文件的内容。

SQLNET.RECV_TIMEOUT=5
SQLNET.INBOUND_CONNECT_TIMEOUT=5

这似乎是问题所在 日志显示 service_died 五秒后的信息 service_register,反复。服务一次又一次地脱离和重新连接到。如果你的JDBC调用恰好在一个注册的对之间开始和结束,那么它们就会工作;如果它们开始了,但还没有结束,那么就会失败。service_died 据报道,。

报道称。文件 这不应该是一个真正的问题--毕竟,它们显示这些值设置为3。

这似乎是一个已知的问题;如果你能访问我的Oracle支持,然后查看 文件ID 2162994.1建议将这些设置增加到大于60或者完全删除--你可能需要弹出数据库来清理它。(如果你没有访问MoS的权限,你可以看到 纲要这并不能告诉你什么,但与你在监听器日志中看到的情况相似)。)

还有其他的问题,在MoS中搜索会发现文档ID 1206583.1和其他的问题,所以可能有一个bug,你可以解决或打补丁--这取决于你使用的Oracle到底是哪个版本和补丁级别。如果有疑问,你可以提出服务请求,当然;前提是你有支持合同。

© www.soinside.com 2019 - 2024. All rights reserved.