【问题记录】Cause: java.sql.SQLRecoverableException: No more data to read from socket

异常说明:

    当Oracle客户端(应用)接收数据库服务器发送的数据时,它会从套接字中读取数据。如果在读取数据的过程中,套接字中没有更多的数据可供读取,那么Oracle客户端就会报告“没有更多数据从套接字读取”错误。

常见原因:

应用使用了连接池,当从连接池取得的connection失效或者超时的时候,使用这个连接来进行数据库操作就会抛出以上异常;
客户端和服务器之间的网络连接存在问题,导致数据传输中断;
数据库服务器上的某个进程崩溃或异常终止,导致无法提供数据;
查询结果集非常庞大,导致传输数据的套接字缓冲区已满;
触发了低版本Oracle的bug

排查方法:

开启连接池的TestQuery(ValidationQuery)等测试连接可用性的配置,检查关闭空闲长连接的配置max_idle_time(客户端空闲连接可用性检查间隔要小于此值),减少空闲连接数。
检查网络连接:确保客户端和服务器之间的网络连接正常。 联系网络管理员查看并确认网络警告日志(拦截或关闭长连接等)。
如果数据库服务器上的某个进程崩溃或终止导致错误发生,联系数据库管理员查找数据库服务的异常警告日志,查看相关线索(killsession)。
增加套接字缓冲区大小:如果查询结果集非常庞大,可以尝试增加传输数据的套接字缓冲区大小。可以通过调整操作系统的TCP缓冲区大小参数来实现。例如,在Linux系统中,可以使用sysctl命令来修改参数。
优化查询语句:如果查询结果集非常庞大,可以考虑优化查询语句以减小结果集的大小。可以使用合适的索引、分页查询或其他方法来限制结果集的大小。
Oracle 11.2.0.4以下版本,可以尝试关闭绑定变量窥探的隐藏参数试试:_optim_peek_user_binds = false

问题解决: 

     联系项目数据库运维人员反馈,出问题的项目Oracle版本为12.2.xxx,同时项目设置了max_idle_time=10(分钟)默认值为0,而应用端使用druid连接池的testWhileIdle=true  、 timeBetweenEvictionRunsMillis=900000 

     经验证通过调整应用端druid timeBetweenEvictionRunsMillis=300000  或修改服务器 max_idle_time=20,都可以解决。

 

另外,联想到之前也遇到过MySQL环境偶发的 Cause: java.sql.SQLException: Connection is closed 问题,是否也是相同的原因导致呢。

 

参考资料:

https://blog.51cto.com/u_16112859/6277609 

https://developer.aliyun.com/article/286959

https://blog.csdn.net/cyzl5/article/details/106262365

https://www.cnblogs.com/lightdb/p/9580463.html 

https://blog.csdn.net/Mr_Runner/article/details/118964470

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...