我想弄清楚为什么我们的Oracle 11g会出现错误行为。我们在所有使用JDBC访问数据库的作业中都出现了以下错误。
Error message: java.sql.SQLRecoverableException: IO Error: Connection reset
在大家不高兴之前,是的,我已经检查了堆栈溢出上的其他相关链接(天知道还有多少其他网站)。到目前为止没有任何帮助,我想知道下一步我可以尝试什么。
在过去的几个月里,情况已经恶化了,唯一改变的是访问数据库的作业是在docker容器中运行的。唯一受影响的数据库是oracle 11g(我们还有其他几个数据库,包括oracle 12c)。我可以使用sqlplus顺利访问11g数据库。
由于这是一个连接的问题,我自然检查了以下文件。tnsnames.ora
和 listener.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.driver.T4CConnection.logon的时候
然后连接被数据库重置了,在认证过程中。(不是被任何网络设备在途中).出现这种情况(登录风暴)的根本原因问题其实是客户端的问题。由于缺乏随机数,客户端无法快速认证自己。当这种情况发生时,那么你可以。
但也有可能是其他原因导致你收到这个错误。
PS:JVM对第2个 "解决方案 "有明确的保护措施(Java bug 6202721)。因为它会影响安全性。所以如果你设置 "java.security.egd=file:devurandom",它会故意忽略你。虽然这个设备名不是黑名单 "java.security.egd=file:dev.urandom"
这里是 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到底是哪个版本和补丁级别。如果有疑问,你可以提出服务请求,当然;前提是你有支持合同。