【问题记录】Cause: java.sql.SQLRecoverableException: No more data to read from socket
Posted on 2024-05-28 14:57 召冠 阅读(1162) 评论(0) 编辑 收藏 举报异常说明:
当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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了