Mysql5的auto Reconnect錯誤

來源:互聯網
上載者:User

http://www.linuxdiyf.com/viewarticle.php?id=89413

 

 

最近在一個J2EE項目的開發過程中,遇到了這樣的問題:

在伺服器上部署好這個Web系統後,這時訪問系統是很正常的。當把伺服器的時間(例如:2008-03-31)加一天或更多天(例如:2008-04-01,2008-04-02...),這時再訪問這個Web系統,報出如下的異常:

QUOTE:
com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception:

** BEGIN NESTED EXCEPTION **

java.io.EOFException

MESSAGE: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.

STACKTRACE:

java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.

at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1997)

at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2411)

at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2916)

at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)

at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)

at com.mysql.jdbc.Connection.execSQL(Connection.java:3250)

at com.mysql.jdbc.Connection.setAutoCommit(Connection.java:5395)

...

我們首先判斷是串連池出了問題,即當系統時間改變後,資料庫連接發現逾時,因此需要重新串連或完全重建串連池。我們換用了一下資料庫,如果使用Oracle資料庫,同樣的修改不會出現問題,系統運行正常,根據不會出現這樣的異常。這就說明了出現這個異常是Mysql相關的,通過查閱資料得知可能和Mysql的運行參數(逾時)有關,順著這個思路我們來分析Mysql的一些運行參數。

在MySQL Command Line Client中執行show variables like '%timeout%';如所示:

在圖中我們可以看到有兩個變數wait_timeout和interactive-timeout,它們的預設值都為28800秒,即為8小時。也就是說預設情況下,Mysql在經過8小時(28800秒)不使用後會自動關閉已開啟的串連。

為瞭解決這個問題,對於MySQL5之前的版本,如Mysql4.x,只需要修改串連池配置中的URL,添加一個參數:autoReconnect=true,如果是MySQL5及以後的版本,則需要修改my.cnf(或者my.ini)檔案,在[mysqld]後面添加上:

wait_timeout = n

interactive-timeout = n

n為伺服器關閉互動式串連前等待活動的秒數。

可是就部署而言每次修改my.ini比較麻煩,而且n等於多少才是合適的呢?所以這個解決辦法不好。

怎麼才能比較好的解決這個問題呢?通過仔細分析,原因大致為:當修改系統日期後Mysql自動關閉已開啟的串連,可以資料庫連接池(DBCP)還認為這些串連是活動的,如果這時有請求(需要執行讀寫資料庫的操作),串連池就用一個串連去操作資料庫,而這個串連在Mysql的串連池中並不存在,所以會出現以上的異常。如果一個串連在和Mysql建立串連時能檢查就不會有這樣的問題了。

這時我們同事想起了他以前用過的一個資料庫連接池proxool,它有兩個屬性:一個是test-before-use,還有一個是test-after-use,這兩個屬性就是在使用前和使用後都要進行對串連的檢查,如果串連無效就扔掉再建立一個新的串連,它們的解釋如下:

test-before-use:

If you set this to true then each connection is tested (with whatever is defined in house-keeping-test-sql) before being served. If a connection fails then it is discarded and another one is picked. If all connections fail a new one is built. If that one fails then you get an SQLException saying so.

test-after-use:

If you set this to true then each connection is tested (with whatever is defined in house-keeping-test-sql) after it is closed (that is, returned to the connection pool). If a connection fails then it is discarded.

於是我們在項目中換上proxool的串連池,再運行並訪問系統,更改系統時間,再訪問,一切OK,問題就這樣解決了!

不但如此,proxool的串連池中的串連的數量,活動數以及每個串連的的具體情況都可以一目瞭然的看到,如所示:

通過上面的測試和分析,針對於Mysql5資料庫,選擇proxool資料庫連接池是比較合適的。

c3p0的串連池有 idleConnectionTestPeriod 屬性,可以設定一段時間後串連池自動化的測試執行,保持串連開放,效果也是一樣的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.