注册
达梦数据库 dm.jdbc.driver.DMException: Communication error 问题分析
专栏/龙山溪笔谈/ 文章详情 /

达梦数据库 dm.jdbc.driver.DMException: Communication error 问题分析

myth8860 2020/12/15 7172 28 0
摘要 达梦数据库 dm.jdbc.driver.DMException: Communication error 问题分析

最近一个项目里面出现了一个比较诡异的问题:页面上有个功能不定期的报错 Communication error

1.png

碰到这种问题我们第一时间怀疑是网络问题,但是客户端工具可以正常连接数据库,页面上其他功能也没报错,所以可以排除网络问题。

为方便跟踪问题,我们可以开启 DM JDBC 的日志,获取更详细的信息

[ERROR - 2020-04-26 11:36:58] tid:262{ conn-33, pstmt-3706 } execute();  
dm.jdbc.driver.DMException: Communication  error
        at dm.jdbc.driver.DBError.throwException(DBError.java:683)
        at dm.jdbc.c.a.a(DBAccess.java:897)
        at dm.jdbc.c.a.a(DBAccess.java:365)
        at dm.jdbc.driver.DmdbPreparedStatement.executeInner(DmdbPreparedStatement.java:212)
        at dm.jdbc.driver.DmdbPreparedStatement.do_execute(DmdbPreparedStatement.java:301)
        at dm.jdbc.filter.FilterChain.PreparedStatement_execute(FilterChain.java:5498)
        at dm.jdbc.filter.log.LogFilter.PreparedStatement_execute(LogFilter.java:8061)
        at dm.jdbc.filter.FilterChain.PreparedStatement_execute(FilterChain.java:5494)
        at dm.jdbc.driver.DmdbPreparedStatement.execute(DmdbPreparedStatement.java:1625)

通过语句句柄:pstmt-3706 可以找到报错的 SQL 语句和它的参数。

2.png

然后我们根据语句和参数自己写了一个小程序进行验证,发现并不会报错,SQL 语句单独在客户端中执行也不会报错,这就有点令人费解了。

接下来我们查一查数据库的 SQL 日志,看看是什么情况。

3.png

从 SQL 日志可以看出报错是-6007:连接异常,并且是在执行几秒钟之后,这种情况很可能是 SQL 超时然后断开了连接。

造成这种情况的有两个可能原因:

  1. 数据库端对用户设置了资源限制。
  2. 应用对 SQL 设置了超时。

经过排查,我们发现数据库并未对用户设置资源限制,仔细分析 JDBC 日志后发现应用调用了 JDBC 的接口设置了连接限制。

--JDBC日志中有很多类似的信息,说明应用针对不同SQL设置了不同的超时时间
setNetworkTimeout(ThreadPoolExecutor, Integer);  [PARAMS]: java.util.concurrent.ThreadPoolExecutor@49e62b17[Running, pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 111], 5000;
 
setNetworkTimeout(ThreadPoolExecutor, Integer);  [PARAMS]: java.util.concurrent.ThreadPoolExecutor@49e62b17[Running, pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 110], 15000;

可是询问客户的开发人员,他们说没有对 SQL 设置超时时间,只在连接池中做了配置,如下:

4.png

显然这个设置和我们分析到的现象不太一致,JDBC 日志里面可以看到应用多次调用接口设置了超时时间,并且每次时间不太一致,应该另有原因,这时我们给客户的开发人员提供了参考文章,主要内容为 JDBC 中还可以用什么方式设置超时,很快客户开发人员就从代码里面找到了超时的设置。

5.png

针对这个原因,有两个解决方案:

治标的方法:修改这个超时的配置,将时间改大一点。
治本的方法:分析一下这个 SQL 语句,将其进一步优化。

本次问题处理的体会:你看到的不一定是真的,你听到的也不一定是真的,要透过现象看本质!

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服