mysql重连,连接丢失:The last packet successfully received from the server–转载

1.1 错误信息:

Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 20,820,001 milliseconds ago.  The last packet sent successfully to the server was 20,820,002 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.
		at sun.reflect.GeneratedConstructorAccessor29.newInstance(Unknown Source) ~[na:na]
		at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.7.0_51]
		at java.lang.reflect.Constructor.newInstance(Constructor.java:526) ~[na:1.7.0_51]
		at com.mysql.jdbc.Util.handleNewInstance(Util.java:411) ~[mysql-connector-java-5.1.29.jar:na]
		at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1129) ~[mysql-connector-java-5.1.29.jar:na]
		at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3988) ~[mysql-connector-java-5.1.29.jar:na]
		at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2598) ~[mysql-connector-java-5.1.29.jar:na]
		at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2778) ~[mysql-connector-java-5.1.29.jar:na]
		at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2828) ~[mysql-connector-java-5.1.29.jar:na]
		at com.mysql.jdbc.ConnectionImpl.setAutoCommit(ConnectionImpl.java:5372) ~[mysql-connector-java-5.1.29.jar:na]
		at com.mchange.v2.c3p0.impl.NewProxyConnection.setAutoCommit(NewProxyConnection.java:881) ~[c3p0-0.9.1.1.jar:0.9.1.1]
		at org.quartz.impl.jdbcjobstore.AttributeRestoringConnectionInvocationHandler.setAutoCommit(AttributeRestoringConnectionInvocationHandler.java:98) ~[quartz-2.2.1.jar:na]

1.2 解决方法

– 如果使用的是JDBC,在JDBC URL上添加?autoReconnect=true,如:

jdbc:mysql://10.10.10.10:3306/mydb?autoReconnect=true

– 如果是在Spring中使用DBCP连接池,在定义datasource增加属性validationQuerytestOnBorrow,如:

<bean id="vrsRankDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${countNew.jdbc.url}" />
    <property name="username" value="${countNew.jdbc.user}" />
    <property name="password" value="${countNew.jdbc.pwd}" />
    <property name="validationQuery" value="SELECT 1" />
    <property name="testOnBorrow" value="true"/>
</bean>

– 如果是在Spring中使用c3p0连接池,则在定义datasource的时候,添加属性testConnectionOnCheckintestConnectionOnCheckout,如:

<bean name="cacheCloudDB" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="${jdbc.driver}"/>
    <property name="jdbcUrl" value="${cache.url}"/>
    <property name="user" value="${cache.user}"/>
    <property name="password" value="${cache.password}"/>
    <property name="initialPoolSize" value="10"/>
    <property name="maxPoolSize" value="${cache.maxPoolSize}"/>
    <property name="testConnectionOnCheckin" value="false"/>
    <property name="testConnectionOnCheckout" value="true"/>
    <property name="preferredTestQuery" value="SELECT 1"/>
</bean>

 

MySQL第二天早上第一次连接超时报错,解决方法com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure Last packet sent to the server was 0 ms ago

最近碰到一个mysql5数据库的问题。就是一个标准的servlet/tomcat网络应用,后台使用mysql数据库。问题是待机一晚上后,第二天早上第一次登录总是失败。察看日志发现如下错误:

“com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

Last packet sent to the server was 0 ms ago.”

经过一番调研,发现很多人都碰到过类似问题,但网上令人满意的回答并不多。mysql网站上的提问也很多,但并没有正确答案;百度知道上倒是有一个近似正确的回答。现将本人的解决办法总结一下:

上述问题是由mysql5数据库的配置引起的。mysql5将其连接的等待时间(wait_timeout)缺省为8小时。在其客户程序中可以这样来查看其值:

mysql﹥

mysql﹥ show global variables like ‘wait_timeout’;

+—————+———+

| Variable_name | Value |

+—————+———+

| wait_timeout | 28800 |

+—————+———+

1 row in set (0.00 sec)

28800 seconds,也就是8小时。

如果在wait_timeout秒期间内,数据库连接(java.sql.Connection)一直处于等待状态,mysql5就将该连接关闭。这时,你的Java应用的连接池仍然合法地持有该连接的引用。当用该连接来进行数据库操作时,就碰到上述错误。这解释了为什么我的程序第二天不能登录 的问题。

你可能会想到在tomcat的数据源配置中有没有办法解决?的确,在jdbc连接url的配置中,你可以附上“autoReconnect=true”,但这仅对mysql5以前的版本起作用。增加“validation query”似乎也无济于事。

本人觉得最简单的办法,就是对症下药:既然问题是由mysql5的全局变量wait_timeout的缺省值太小引起的,我们将其改大就好了。

查看mysql5的手册,发现对wait_timeout的最大值分别是24天/365天(windows/linux)。以windows为 例,假设我们要将其设为21天,我们只要修改mysql5的配置文件“my.ini”(mysql5 installation dir),增加一行:wait_timeout=1814400

365天:

wait_timeout=31536000

interactive_timeout=31536000

需要重新启动mysql5。


quartz将配置保存在数据库时,如果数据库和quartz断连接,那么quartz读取数据库时会发生异常。

做如下配置:

  1. org.quartz.dataSource.myDS.driver = org.mariadb.jdbc.Driver
  2. org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/dxtdatabase?useUnicode=true&characterEnco
  3. ding=UTF-8&autoReconnect=true&autoReconnectForPools=true
  4. org.quartz.dataSource.myDS.user = root
  5. org.quartz.dataSource.myDS.password = 123456
  6. org.quartz.dataSource.myDS.maxConnections = 30
  7. org.quartz.dataSource.myDS.validateOnCheckout = true
  8. org.quartz.dataSource.myDS.validationQuery = select 1
  1. org.quartz.dataSource.myDS.validateOnCheckout = true
  2. org.quartz.dataSource.myDS.validationQuery = select 1

这两个配置的意思是使用连接时先判断是否有效。

  1. &autoReconnect=true&autoReconnectForPools=true  

这个配置没有效果,是开始尝试的第一个方案,没有坏的影响就没删。

发表评论

电子邮件地址不会被公开。 必填项已用*标注