记一次mysql线上问题排查

举报
xindoo 发表于 2022/04/16 00:55:54 2022/04/16
【摘要】   背景是这样的,我们有个系统每天都会调起多个定时任务,首先quartz每分钟会调起一次检查时间的任务,如果发现时间到达设定的任务执行时间,java代码会向数据库里写入一条记录,然后有另外一个系统就会根据...

  背景是这样的,我们有个系统每天都会调起多个定时任务,首先quartz每分钟会调起一次检查时间的任务,如果发现时间到达设定的任务执行时间,java代码会向数据库里写入一条记录,然后有另外一个系统就会根据这条记录执行相应的任务,有天有同事反馈说有条定时任务没执行。。
  后来排查发现,这条定时任务从5月多开始,偶尔才执行一次,不执行的时候都是这条记录写不到库里,将这条定时任务执行时间调后之后就可以正常执行了,但是又有另外一条定时任务不执行了……啊啊啊这是什么鬼bug。峰回路转,我在日志里发现了这样一条记录。

### Error querying database.  Cause: org.apache.ibatis.transaction.TransactionException: Error configuring AutoCommit.  Your driver may not support getAutoCommit() or setAutoCommit(). Requested setting: false.  Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 40,655,368 milliseconds ago.  The last packet sent successfully to the server was 40,655,368 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
### The error may exist in xxxx/dao/MybatisDBOperation.java (best guess)
### The error may involve xxx.dao.MybatisDBOperation.getTemplateIdById
### The error occurred while executing a query
### Cause: org.apache.ibatis.transaction.TransactionException: Error configuring AutoCommit.  Your driver may not support getAutoCommit() or setAutoCommit(). Requested setting: false.  Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 40,655,368 milliseconds ago.  The last packet sent successfully to the server was 40,655,368 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.

  原来是第一次写库会写失败,google这段报错,发现网上有人说mysql端会释放超过一段时间的空闲链接,默认8小时。如果你拿着已经被mysql释放的链接去读写库,肯定会失败。联系我司dba后发现,如果java端连接池没管理好,确实会出现这个问题。而且这样可以完美解释为啥有时候第一次写库会成功,我看了下第一条定时任务成功那几天,都是有人在20点后操作过系统(我定时任务4点开始执行),这样connection刚好没有超时,可以接着用。
  问题的原因找到了,其实就是我用了mybatis,mybatis自己维护了一个连接池,但是没对连接池里的链接有效性做校验。

解决方案一

  把mysql段的超时时间设大,从默认的8小时设置到24小时。因为我们的系统至少每天都会有读写mysql的操作,24小时肯定能覆盖的一个完整的读写库周期。但其实这种方法治标不治本。

解决方案二

  写个定时任务定期读一次数据库,保证mybatis维护的connection都是有效的,这是一个很low的方案,但确实有效啊。

解决方案三

  更方案二差不多,都是定时查库,但是不是写定时任务,而是又mybatis自己定时去查。所以需要在mybatis配置里加上以下几行配置

//开启mybatis的poolping功能
<property name="poolPingEnabled" value="true"/>
//select 1其实是定期执行的sql
<property name="poolPingQuery" value="select 1"/>
//表示无数据库操作3600000ms(1h)执行一次poolping
<property name="poolPingConnectionsNotUsedFor" value="3600000"/>

  看了下同事c3p0配置,发现c3p0中有周期性对连接池中链接有效性做校验的功能,对mybatis不是特别了解,不知道mybatis有没有类似的功能(估计肯定会有)。

c3p0.idleConnectionTestPeriod=60

文章来源: xindoo.blog.csdn.net,作者:xindoo,版权归原作者所有,如需转载,请联系作者。

原文链接:xindoo.blog.csdn.net/article/details/74011187

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。