mysql 8小時空閒後鏈接超時的問題

近一段時間,部門同事反映在使用mysql的過程出現數據庫鏈接問題java

應用程序和數據庫創建鏈接,若是超過8小時應用程序不去訪問數據庫,數據庫就斷掉鏈接 。這時再次訪問就會拋出異常,以下所示:mysql

java.io.EOFException
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1913)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2304)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2803)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1573)
...

查了一下發現應用程序和mysql數據庫創建鏈接,若是超過8小時應用程序不去訪問數據庫,數據庫就斷掉鏈接 。這時再次訪問就會拋出異常。
sql

關於mysql自動斷開的問題研究結果以下,在mysql中有相關參數設定,當數據庫鏈接空閒必定時間後,服務器就會斷開等待超時的鏈接:
一、相關參數,紅色部分
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,結果出人意料,系統自動將這個值設置爲1。換句話說,不能將該值設置爲永久。
將這2個參數設置爲24小時(60*60*24=604800)便可。
set interactive_timeout=604800;
set wait_timeout=604800;服務器

也能夠修改my.cof,修改後重起mysql
打開/etc/my.cnf,在屬性組mysqld下面添加參數以下:
[mysqld]
interactive_timeout=28800000
wait_timeout=28800000app

若是一段時間內沒有數據庫訪問則mysql自身將切斷鏈接,以後訪問java訪問鏈接池時對數據庫的數據通道早就關閉了,由於dbcp鏈接池沒法時時維護與數據庫的鏈接關係,mysql5之後即便在dbcp配置中加入autoReconnect=true也沒有效果。ide


另一種解決辦法是,經過鏈接池在空閒時自動從新鏈接解決這個問題,以下是hibernate鏈接池的實現方法:測試

<?xml version="1.0" encoding="UTF-8"?>
<!-- the proxool configuration can be embedded within your own application's.
Anything outside the "proxool" tag is ignored. -->
<something-else-entirely>
<proxool>
<!-- proxool別名 -->
<alias>product</alias>
<!-- 數據庫鏈接Url -->
<driver-url>jdbc:mysql://db:3306/product?useUnicode=true&amp;characterEncoding=utf8</driver-url>
<!-- JDBC驅動名稱 -->
<driver-class>com.mysql.jdbc.Driver</driver-class>
<!-- 數據庫鏈接賬卿-->
<driver-properties>
<property name="user" value="chinawidth" />
<property name="password" value="123456" />
</driver-properties>
<!-- proxool自動偵察各個鏈接狀態的時間間隔(毫秒),偵察到空閒的鏈接就立刻回撿超時的銷歿-->
<house-keeping-sleep-time>90000</house-keeping-sleep-time>
<!-- 指因未有空閒鏈接能夠分配而在隊列中等候的最大請求數,超過這個請求數的用戶鏈接就不會被接受 -->
<maximum-new-connections>20</maximum-new-connections>
<!-- 最少保持的空閒鏈接擿-->
<prototype-count>3</prototype-count>
<!-- 容許最大鏈接數,超過了這個鏈接,再有請求時,就排在隊列中等候,最大的等待請求數由maximum-new-

connections決定 -->
<maximum-connection-count>20</maximum-connection-count>
<!-- 最小鏈接數 -->
<minimum-connection-count>3</minimum-connection-count>
<!-- 在分配鏈接先後是否進行有效性測試,這個是解決本問題的關鈿-->
<test-before-use>true</test-before-use>
<test-after-use>true</test-after-use>
<!-- 用於測試的SQL語句 --> <house-keeping-test-sql>SELECT CURRENT_USER</house-keeping-test-sql> </proxool> </something-else-entirely>
相關文章
相關標籤/搜索