设为首页 收藏本站
查看: 758|回复: 0

[经验分享] 关于MySQL的wait

[复制链接]

尚未签到

发表于 2017-12-12 23:21:48 | 显示全部楼层 |阅读模式
  bug回顾 :
  想必大家在用MySQL时都会遇到连接超时的问题,如下图所示:
  

### Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 47,795,922 milliseconds ago.  The last packet sent successfully to the server was 47,795,922 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.  
; SQL []; The last packet successfully received from the server was 47,795,922 milliseconds ago.  The last packet sent successfully to the server was 47,795,922 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.; nested exception is com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 47,795,922 milliseconds ago.  The last packet sent successfully to the server was 47,795,922 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.
  

  大概意思是当前的connection所进行过的最新请求是在52,587秒之前,这个时间是大于服务所配置的wait_timeout时间的。
  原因分析:
  MySQL连接时,服务器默认的“wait_timeout”是8小时,也就是说一个connection空闲超过8个小时,Mysql将自动断开该connection。connections如果空闲超过8小时,Mysql将其断开,而DBCP连接池并不知道该connection已经失效,如果这时有Client请求connection,DBCP将该失效的Connection提供给Client,将会造成异常。
  mysql分析:
  打开MySQL的控制台,运行:show variables like ‘%timeout%’,查看和连接时间有关的MySQL系统变量,得到如下结果:
DSC0000.png

  其中wait_timeout就是负责超时控制的变量,其时间为长度为28800s,就是8个小时,那么就是说MySQL的服务会在操作间隔8小时后断开,需要再次重连。也有用户在URL中使用jdbc.url=jdbc:mysql://localhost:3306/nd?autoReconnect=true来使得连接自动恢复,当然了,这是可以的,不过是MySQL4及其以下版本适用。MySQL5中已经无效了,必须调整系统变量来控制了。MySQL5手册中对两个变量有如下的说明:
  interactive_timeout:服务器关闭交互式连接前等待活动的秒数。交互式客户端定义为在mysql_real_connect()中使用CLIENT_INTERACTIVE选项的客户端。又见wait_timeout
  wait_timeout:服务器关闭非交互连接之前等待活动的秒数。在线程启动时,根据全局wait_timeout值或全局interactive_timeout值初始化会话wait_timeout值,取决于客户端类型(由mysql_real_connect()的连接选项CLIENT_INTERACTIVE定义),又见interactive_timeout
  如此看来,两个变量是共同控制的,那么都必须对他们进行修改了。继续深入这两个变量wait_timeout的取值范围是1-2147483(Windows),1-31536000(linux),interactive_time取值随wait_timeout变动,它们的默认值都是28800。
  MySQL的系统变量由配置文件控制,当配置文件中不配置时,系统使用默认值,这个28800就是默认值。要修改就只能在配置文件里修改。Windows下在%MySQL HOME%/bin下有mysql.ini配置文件,打开后在如下位置添加两个变量,赋值。(这里修改为388000)
  解决方式:

1. 增加 MySQL 的 wait_timeout 属性的值 (不推荐)
  修改mysql安装目录下的配置文件 my.ini文件(如果没有此文件,复制“my-default.ini”文件,生成“复件 my-default.ini”文件。将“复件 my-default.ini”文件重命名成“my.ini” ),在文件中设置:
  

wait_timeout=31536000  
interactive_timeout=31536000  
  


这两个参数的默认值是8小时(60*60*8=28800)。 注意: 1.wait_timeout的最大值只允许2147483 (24天左右)  也可以使用mysql命令对这两个属性进行修改
DSC0001.png


2. 减少连接池内连接的生存周期
  减少连接池内连接的生存周期,使之小于上一项中所设置的wait_timeout 的值

修改 c3p0 的配置文件,在 Spring 的配置文件中设置:  

<bean >  <property name="maxIdleTime"value="1800"/>  
  <!--other properties -->  
  </bean>
  


3. 定期使用连接池内的连接

定期使用连接池内的连接,使得它们不会因为闲置超时而被 MySQL 断开。
修改 c3p0 的配置文件,在 Spring 的配置文件中设置:  

<bean>  <property name="preferredTestQuery" value="SELECT 1"/>  
  <property name="idleConnectionTestPeriod" value="18000"/>  
  <property name="testConnectionOnCheckout" value="true"/>  
  
</bean>
  

  附上dbcp和c3p0的标准配置
  

<bean>  <property name="driverClassName" value="com.mysql.jdbc.Driver" />
  <property name="url" value="jdbc:mysql://192.168.40.10:3336/XXX" />
  <property name="username" value="" />
  <property name="password" value="" />
  <property name="maxWait" value="20000"></property>
  <property name="validationQuery" value="SELECT 1"></property>
  <property name="testWhileIdle" value="true"></property>
  <property name="testOnBorrow" value="true"></property>
  <property name="timeBetweenEvictionRunsMillis" value="3600000"></property>
  <property name="numTestsPerEvictionRun" value="50"></property>
  <property name="minEvictableIdleTimeMillis" value="120000"></property>
  <property name="removeAbandoned" value="true"/>
  <property name="removeAbandonedTimeout" value="6000000"/>
  
</bean>
  

  

<bean destroy-method="close">  
  <property name="driverClass"><value>oracle.jdbc.driver.OracleDriver</value></property>   
  
  <property name="jdbcUrl"><value>jdbc:oracle:thin:@localhost:1521:Test</value></property>   
  
  <property name="user"><value>Kay</value></property>   
  
  <property name="password"><value>root</value></property>   
  
  <!--连接池中保留的最小连接数。-->   
  
  <property name="minPoolSize" value="10" />   
  
  <!--连接池中保留的最大连接数。Default: 15 -->   
  
  <property name="maxPoolSize" value="100" />   
  
  <!--最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->   
  
  <property name="maxIdleTime" value="1800" />   
  
  <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->   
  
  <property name="acquireIncrement" value="3" />   
  
  <property name="maxStatements" value="1000" />   
  
  <property name="initialPoolSize" value="10" />   
  
  <!--每60秒检查所有连接池中的空闲连接。Default: 0 -->   
  
  <property name="idleConnectionTestPeriod" value="60" />   
  
  <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->   
  
  <property name="acquireRetryAttempts" value="30" />   
  
  <property name="breakAfterAcquireFailure" value="true" />   
  
  <property name="testConnectionOnCheckout" value="false" />   
  
</bean>   
  

  参考:
  https://my.oschina.net/guanzhenxing/blog/213364
  http://sarin.iteye.com/blog/580311/
  http://blog.csdn.net/wangfayinn/article/details/24623575

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-423495-1-1.html 上篇帖子: mysql 索引长度和区分度 下篇帖子: mysql中查看索引是否被使用到
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表