mysql超经典的8小时问题-wait_timeout

举报
红目香薰 发表于 2022/01/21 23:27:39 2022/01/21
【摘要】 经常作妖的问题,咱们一起干掉它。  异常如下: java.io.EOFExceptionat at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1913)at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.jav...

经常作妖的问题,咱们一起干掉它。

 异常如下:


  
  1. java.io.EOFExceptionat
  2. at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1913)
  3. at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2304)
  4. at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2803)
  5. at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1573)

场景出现的理论依据
MySQL 的默认设置下,当一个连接的空闲时间超过8小时后,MySQL 就会断开该连接,而 c3p0/dbcp 连接池则以为该被断开的连接依然有效。在这种情况下,如果客户端代码向c3p0/dbcp 连接池请求连接的话,连接池就会把已经失效的连接返回给客户端,客户端在使用该失效连接的时候即抛出异常。

如果你只是个程序员,你会想着,在去对数据库做操作前,我不是先对数据库连接做个校验或判断什么的,连接是working的,我才干活,那么你得到的解决方案-或许就是这样的


  
  1. #c3p0配置
  2. <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。默认值: 0 -->
  3. <property name="maxIdleTime">60</property>
  4. <!-- 当连接池连接耗尽时,客户端调用getConnection()后等待获取新连接的时间,
  5. 超时后将抛出SQLException,如设为0则无限期等待。单位毫秒。默认: 0 -->
  6. <property name="checkoutTimeout" value="3000"/>
  7. <!--c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。
  8. 如果定义了这个参数那么属性preferredTestQuery将被忽略。
  9. 你不能在这张Test表上进行任何操作,它将只供c3p0测试使用。默认值: null -->
  10. <property name="automaticTestTable">Test</property>
  11. <!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的
  12.   时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable
  13.   等方法来提升连接测试的性能。Default: false -->
  14. <property name="testConnectionOnCheckout">false</property>
  15. <!--如果设为true那么在取得连接的同时将校验连接的有效性。Default: false -->
  16. <property name="testConnectionOnCheckin">true</property>
  17. <!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
  18. <property name="idleConnectionTestPeriod">60</property>

如果你只是个DBA,你会想着,为什么数据库连接自己断了,是不是哪里有配置,我得去看看,那么你得到的解决方案-可能就是这样的


  
  1. #my.cnf
  2. wait_timeout=31536000
  3. interactive_timeout=31536000

加大wait_timeout的时间?

但是现实环境中需要你考虑的是:

  1. 你设置多久检查一次连接有效的时间 依据是什么?
  2. 默认加大/减小wait_timeout除了解决当前问题,会不会带来其他影响?

个人当前觉得此题 第一需考虑的是:
你业务当前高峰期mysql_connection是多少?保留多久connection在高峰期都不会撑爆你数据库连接池?
如果你知道这个池-那么是改mysql ?还是改c3p0?还是双管齐下都是有据可循且不会带来后遗症的-最佳解决方案

如我当前有环境,一个现网的后台管理系统,使用人数在50以内,那么我wait_timeout 就是默认8小时,c3p0不用做连接有效性检查等,都是万事ok的。

而我还有一个EPG前台管理系统,用户量在300万以内,如果我wait_timeout为8小时,那我一到高峰期肯定就是死翘翘的,会有太多的TCP连接没关闭,
数据库连接数肯定是不够的。
因EPG的一个访问-一次对数据库操作量不大,查询完数据就完成ok啦,wait_timeout 设置在120s内应该是够用啦,那么相对应的c3p0中 设置小于wait_timeout 的时间有效性检查 -就能确保获取到连接是有效的。

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

原文链接:laoshifu.blog.csdn.net/article/details/115337296

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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