Oracle11g:JDBC作业中止,并带有;IO错误:连接重置“;
我正试图弄明白为什么我们的甲骨文11g一直行为不端。在使用JDBC访问数据库的所有作业中,我们都遇到以下错误:Oracle11g:JDBC作业中止,并带有;IO错误:连接重置“;,oracle,jdbc,Oracle,Jdbc,我正试图弄明白为什么我们的甲骨文11g一直行为不端。在使用JDBC访问数据库的所有作业中,我们都遇到以下错误: Error message: java.sql.SQLRecoverableException: IO Error: Connection reset 在任何人感到不安之前,是的,我已经检查了stack overflow上的其他相关链接(天知道还有多少其他站点)。到目前为止,一切都无济于事,我想知道下一步我能做些什么 在过去几个月里,情况恶化了,唯一改变的是访问数据库的作业在dock
Error message: java.sql.SQLRecoverableException: IO Error: Connection reset
在任何人感到不安之前,是的,我已经检查了stack overflow上的其他相关链接(天知道还有多少其他站点)。到目前为止,一切都无济于事,我想知道下一步我能做些什么
在过去几个月里,情况恶化了,唯一改变的是访问数据库的作业在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
但是,这并没有解决问题,针对数据库运行的作业仍在中止
最令人恼火的是,有时作业会毫无差错地完成。如果有人能告诉我应该朝哪个方向看,我将不胜感激
编辑:
根据要求,以下是sqlnet.ora文件的内容:
SQLNET.RECV_TIMEOUT=5
SQLNET.INBOUND_CONNECT_TIMEOUT=5
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
所以我们说的是几十个连接,而不是几百个
Edit2:为了完整起见,这里是堆栈跟踪的一部分:
****** 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上 然后,在身份验证期间,数据库重置了连接。(路上没有任何网络设备)。 这种情况的根本原因(登录风暴)实际上是客户端的问题。由于缺少随机数,客户端无法足够快地进行身份验证。发生这种情况时,您可以:
- 调整内核参数以在缓冲区中保存更多随机数(客户端)
- 当JVM使用另一个/dev/*随机设备(客户端)时,请使用该技巧
- 更改参数SQLNET.INBOUND\u CONNECT\u TIMEOUT以延长服务器等待客户端(db服务器)时的时间窗口
SQLNET.RECV_TIMEOUT=5
SQLNET.INBOUND_CONNECT_TIMEOUT=5
SQLNET.RECV_TIMEOUT=5
SQLNET.INBOUND_CONNECT_TIMEOUT=5
这似乎就是问题所在。日志会在服务注册
五秒钟后反复显示服务
消息。服务正在一次又一次地从服务器上分离和重新连接。您的JDBC调用work,如果它们恰好在寄存器/死亡对之间开始和结束;如果在报告服务死亡时启动但尚未完成,则会失败
据我所知,这不应该是一个真正的问题——毕竟,它们将这些值设置为3
这似乎是一个已知的问题;如果您可以访问我的Oracle支持,请查看,这建议将这些设置增加到大于60,或者将它们全部删除—您可能需要跳出数据库来清理它。(如果您没有访问MoS的权限,您可以查看,这不会告诉您太多,但与您在侦听器日志中看到的内容类似。)
还有其他问题,在MoS中搜索会发现文档ID 1206583.1和其他问题,因此可能存在可以解决或修补的错误-这取决于您使用的Oracle的确切版本和修补级别。如果您有疑问,当然可以提出服务请求;假设您有一份支持合同。当它工作时,需要多长时间?少于5秒?你能包括你的sqlnet.ora
文件工具吗它有sent\u timeout
和recv\u timeout
设置(大概设置为5)?我已经在帖子中添加了sqlnet.ora的内容。至于连接数据库需要多长时间,我们讨论的是连接数据库通常需要多长时间。我写的作业是在不同的时间创建jdbc连接,用于读取数据、读取目录数据、更新表等等。为什么它有时会工作,有时不会,这就是我需要弄清楚的。它是否工作取决于JDBC调用是否与service\u
消息一致,大概(再次!)。比较日志应该能说明这一点。通话越短,越有可能逃脱处罚;我认为,一个持续五秒钟以上的手术总是失败的。至于SQL*Plus,这是一个本地遗留连接吗?它不依赖SQL*Net,因此不会受到影响?如果通过服务名称进行连接,您是否发现问题?例如,sqlplus-usr/pwd@//linuxoracle11:1521/TMF
?@Alex-Poole:比较日志?哪一个?这对我来说是个问题,因为甲骨文松鼠在各种地方记录和发出警报。我通常需要做一个复杂的“查找”来有机会找到一个。您对sqlplus的猜测是正确的。它在服务器上运行,因此不受sqlnet问题的影响