mysql經典的8小時問題-wait_timeout


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

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 連接池請求連接的話,連接池就會把已經失效的連接返回給客戶端,客戶端在使用該失效連接的時候即拋出異常。

如果你只是個程序員,你會想着,在去對數據庫做操作前,我不是先對數據庫連接做個校驗或判斷什么的,連接是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,你會想着,為什么數據庫連接自己斷了,是不是哪里有配置,我得去看看,那么你得到的解決方案-可能就是這樣的

#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的。

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM