mysql經典的8小時問題-wait_timeout

前段時間 現網忽然頻繁報出 鏈接不上數據庫,偶滴的妖孽,其餘地方都是用mysql,也沒遇到這個問題呀。java

java.io.EOFExceptionat 
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小時後,MySQL 就會斷開該鏈接,而 c3p0/dbcp 鏈接池則覺得該被斷開的鏈接依然有效。在這種狀況下,若是客戶端代碼向c3p0/dbcp 鏈接池請求鏈接的話,鏈接池就會把已經失效的鏈接返回給客戶端,客戶端在使用該失效鏈接的時候即拋出異常。mysql

若是你只是個程序員,你會想着,在去對數據庫作操做前,我不是先對數據庫鏈接作個校驗或判斷什麼的,鏈接是working的,我才幹活,那麼你獲得的解決方案-或許就是這樣的程序員

#c3p0配置
<!--最大空閒時間,60秒內未使用則鏈接被丟棄。若爲0則永不丟棄。默認值: 0 -->   
<property name="maxIdleTime">60</property>  
<!-- 當鏈接池鏈接耗盡時,客戶端調用getConnection()後等待獲取新鏈接的時間,
超時後將拋出SQLException,如設爲0則無限期等待。單位毫秒。默認: 0 -->   
<property name="checkoutTimeout" value="3000"/>  
<!--c3p0將建一張名爲Test的空表,並使用其自帶的查詢語句進行測試。
若是定義了這個參數那麼屬性preferredTestQuery將被忽略。
你不能在這張Test表上進行任何操做,它將只供c3p0測試使用。默認值: null -->   
 <property name="automaticTestTable">Test</property>  
<!--因性能消耗大請只在須要的時候使用它。若是設爲true那麼在每一個connection提交的   
  時候都將校驗其有效性。建議使用idleConnectionTestPeriod或automaticTestTable   
  等方法來提高鏈接測試的性能。Default: false -->   
<property name="testConnectionOnCheckout">false</property>   
<!--若是設爲true那麼在取得鏈接的同時將校驗鏈接的有效性。Default: false -->   
<property name="testConnectionOnCheckin">true</property> 
<!--每60秒檢查全部鏈接池中的空閒鏈接。Default: 0 -->   
<property name="idleConnectionTestPeriod">60</property>

若是你只是個DBA,你會想着,爲何數據庫鏈接本身斷了,是否是哪裏有配置,我得去看看,那麼你獲得的解決方案-可能就是這樣的sql

#my.cnf
wait_timeout=31536000  
interactive_timeout=31536000

加大wait_timeout的時間。數據庫

But 現實環境中須要你考慮的是:性能

  1. 你設置多久檢查一次鏈接有效的時間 依據是什麼?
  2. 默認加大/減少wait_timeout除了解決當前問題,會不會帶來其餘影響?

我的當前以爲此題 第一需考慮的是:
你業務當前高峯期mysql_connection是多少?保留多久connection在高峯期都不會撐爆你數據庫鏈接池?
若是你知道這個池-那麼是改mysql ?仍是改c3p0?仍是左右開弓都是有據可循且不會帶來後遺症的-最佳解決方案
測試

如我當前有環境,一個現網的後臺管理系統,使用人數在50之內,那麼我wait_timeout 就是默認8小時,c3p0不用作鏈接有效性檢查等,都是萬事ok的。code

而我還有一個EPG前臺管理系統,用戶量在300萬之內,若是我wait_timeout爲8小時,那我一到高峯期確定就是死翹翹的,會有太多的TCP鏈接沒關閉,
數據庫鏈接數確定是不夠的。
因EPG的一個訪問-一次對數據庫操做量不大,查詢完數據就完成ok啦,wait_timeout 設置在120s內應該是夠用啦,那麼相對應的c3p0中 設置小於wait_timeout 的時間有效性檢查 -就能確保獲取到鏈接是有效的。get

請根據業務場景,來配置參數,不要解決了A問題,帶來了B問題。it

做者:灼灼2015 連接:https://www.jianshu.com/p/69dcae4454b3 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。

相關文章
相關標籤/搜索