zoukankan      html  css  js  c++  java
  • mysql连接的空闲时间超过8小时后 MySQL自动断开该连接解决方案

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

    解决这个问题的办法有三种:

    1. 增加 MySQL 的 wait_timeout 属性的值。

    修改 /etc/mysql/my.cnf文件,在 [mysqld] 节中设置:

    # Set a connection to wait 8hours in idle status.
    wait_timeout =86400
    相关参数,红色部分
    mysql> show variables like '%timeout%';
    +--------------------------+-------+
    | Variable_name        | Value |
    +--------------------------+-------+
    | connect_timeout     | 5       |
    | delayed_insert_timeout | 300 |
    | innodb_lock_wait_timeout | 50 |
    | interactive_timeout | 28800 |
    | net_read_timeout | 30 |
    | net_write_timeout | 60 |
    | slave_net_timeout | 3600 |
    | wait_timeout | 28800 |
    +--------------------------+-------+
    同一时间,这两个参数只有一个起作用。到底是哪个参数起作用,和用户连接时指定的连接参数相关,缺省情况下是使用wait_timeout。我建议是将这两个参数都修改,以免引起不必要的麻烦。

    这两个参数的默认值是8小时(60*60*8=28800)。我测试过将这两个参数改为0,结果出人意料,系统自动将这个值设置为。换句话说,不能将该值设置为永久。
    将这2个参数设置为24小时(60*60*24=604800)即可。
    set interactive_timeout=604800;
    set wait_timeout=604800;

    2. 减少连接池内连接的生存周期,使之小于上一项中所设置的 wait_timeout 的值。
    修改 c3p0 的配置文件,设置:

    # How long to keep unused connections around(in seconds)
    # Note: MySQL times out idle connections after 8hours(28,800seconds)
    # so ensure this value is below MySQL idle timeout
    cpool.maxIdleTime=25200
    在 Spring 的配置文件中:

      <bean id="dataSource"
      class="com.mchange.v2.c3p0.ComboPooledDataSource">
      <property name="maxIdleTime"value="${cpool.maxIdleTime}"/>
      <!--other properties -->
      </bean>

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

    # Prevent MySQL raise exception after a long idle timecpool.preferredTestQuery='SELECT 1'cpool.idleConnectionTestPeriod=18000cpool.testConnectionOnCheckout=true
    修改 Spring 的配置文件:

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="preferredTestQuery" value="${cpool.preferredTestQuery}"/>
    <property name="idleConnectionTestPeriod" value="${cpool.idleConnectionTestPeriod}"/>
    <property name="testConnectionOnCheckout" value="${cpool.testConnectionOnCheckout}"/>
    <!--other properties --></bean>

    附:Mysql经典的“8小时问题”

    MySQL 的默认设置下,当一个连接的空闲时间超过8小时后,MySQL 就会断开该连接,而 c3p0 连接池则以为该被断开的连接依然有效。

    假设你的数据库是mysql,如果数据源配置不当,将可能发生经典的“8小时问题”。原因是mysql在默认情况下,如果发现一个连接的空闲时间超过8小时,将会在数据库端自动关闭这个连接。而数据源并不知道这个连接已经关闭了,当它将这个无用的连接返回给某个dao时,dao就会报无法获取connection异常。

        如果采用dbcp的默认配置,由于testOnBorrow属性的默认值是true,数据源在将连接交给dao前,会事先检测这个连接是否是好的,如果连接有问题(在数据库端被关闭),则会取一个其他的连接给dao。所以并不会有“8小时问题”。如果每次将连接交给dao时都检测连接的有效性,在高并发的应用中将会带来性能的问题,因为它会需要更多的数据库访问请求。

        一种推荐的高效的方式是:将testOnBorrow设置为false,而将“testWhileIdle”设置为true,再设置好testBetweenEvictionRunsMillis值(小于8小时)。那些被mysql关闭的连接就可以别清除出去,避免“8小时问题”。

        当然,mysql本身也能调整interactive-timeout(以秒为单位)配置参数,更改空闲连接的过期时间。所以,在设置timeBetweenEvictionRunsmMillis值时,必须首先获知mysql的空闲连接的最大过期时间。

        c3p0对于有效连接的检测,请参照dbcp配置方式。

    以上所述就是本文的全部内容了,希望大家能够喜欢。

  • 相关阅读:
    Azkaban的使用
    Azkaban安装
    Kafka 启动失败,报错Corrupt index found以及org.apache.kafka.common.protocol.types.SchemaException: Error reading field 'version': java.nio.BufferUnderflowException
    Kafka 消费者设置分区策略及原理
    Kafka利用Java API自定义生产者,消费者,拦截器,分区器等组件
    zookeeper群起总是有那么几个节点起不来的问题解决
    flume 启动agent报No appenders could be found for logger的解决
    Flume 的监控方式
    Flume 自定义 组件
    Source r1 has been removed due to an error during configuration java.lang.IllegalArgumentException: Required parameter bind must exist and may not be null & 端口无法连接
  • 原文地址:https://www.cnblogs.com/nxmxl/p/11831166.html
Copyright © 2011-2022 走看看