mysql超经典的8小时问题-wait_timeout
經(jīng)常作妖的問題,咱們一起干掉它。
?異常如下:
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)場景出現(xiàn)的理論依據(jù)
MySQL 的默認(rèn)設(shè)置下,當(dāng)一個(gè)連接的空閑時(shí)間超過8小時(shí)后,MySQL 就會(huì)斷開該連接,而 c3p0/dbcp 連接池則以為該被斷開的連接依然有效。在這種情況下,如果客戶端代碼向c3p0/dbcp 連接池請(qǐng)求連接的話,連接池就會(huì)把已經(jīng)失效的連接返回給客戶端,客戶端在使用該失效連接的時(shí)候即拋出異常。
如果你只是個(gè)程序員,你會(huì)想著,在去對(duì)數(shù)據(jù)庫做操作前,我不是先對(duì)數(shù)據(jù)庫連接做個(gè)校驗(yàn)或判斷什么的,連接是working的,我才干活,那么你得到的解決方案-或許就是這樣的
#c3p0配置 <!--最大空閑時(shí)間,60秒內(nèi)未使用則連接被丟棄。若為0則永不丟棄。默認(rèn)值: 0 --> <property name="maxIdleTime">60</property> <!-- 當(dāng)連接池連接耗盡時(shí),客戶端調(diào)用getConnection()后等待獲取新連接的時(shí)間, 超時(shí)后將拋出SQLException,如設(shè)為0則無限期等待。單位毫秒。默認(rèn): 0 --> <property name="checkoutTimeout" value="3000"/> <!--c3p0將建一張名為Test的空表,并使用其自帶的查詢語句進(jìn)行測試。 如果定義了這個(gè)參數(shù)那么屬性preferredTestQuery將被忽略。 你不能在這張Test表上進(jìn)行任何操作,它將只供c3p0測試使用。默認(rèn)值: null --> <property name="automaticTestTable">Test</property> <!--因性能消耗大請(qǐng)只在需要的時(shí)候使用它。如果設(shè)為true那么在每個(gè)connection提交的 時(shí)候都將校驗(yàn)其有效性。建議使用idleConnectionTestPeriod或automaticTestTable 等方法來提升連接測試的性能。Default: false --> <property name="testConnectionOnCheckout">false</property> <!--如果設(shè)為true那么在取得連接的同時(shí)將校驗(yàn)連接的有效性。Default: false --> <property name="testConnectionOnCheckin">true</property> <!--每60秒檢查所有連接池中的空閑連接。Default: 0 --> <property name="idleConnectionTestPeriod">60</property>如果你只是個(gè)DBA,你會(huì)想著,為什么數(shù)據(jù)庫連接自己斷了,是不是哪里有配置,我得去看看,那么你得到的解決方案-可能就是這樣的
#my.cnf wait_timeout=31536000 interactive_timeout=31536000加大wait_timeout的時(shí)間?
但是現(xiàn)實(shí)環(huán)境中需要你考慮的是:
個(gè)人當(dāng)前覺得此題 第一需考慮的是:
你業(yè)務(wù)當(dāng)前高峰期mysql_connection是多少?保留多久connection在高峰期都不會(huì)撐爆你數(shù)據(jù)庫連接池?
如果你知道這個(gè)池-那么是改mysql ?還是改c3p0?還是雙管齊下都是有據(jù)可循且不會(huì)帶來后遺癥的-最佳解決方案
如我當(dāng)前有環(huán)境,一個(gè)現(xiàn)網(wǎng)的后臺(tái)管理系統(tǒng),使用人數(shù)在50以內(nèi),那么我wait_timeout 就是默認(rèn)8小時(shí),c3p0不用做連接有效性檢查等,都是萬事ok的。
而我還有一個(gè)EPG前臺(tái)管理系統(tǒng),用戶量在300萬以內(nèi),如果我wait_timeout為8小時(shí),那我一到高峰期肯定就是死翹翹的,會(huì)有太多的TCP連接沒關(guān)閉,
數(shù)據(jù)庫連接數(shù)肯定是不夠的。
因EPG的一個(gè)訪問-一次對(duì)數(shù)據(jù)庫操作量不大,查詢完數(shù)據(jù)就完成ok啦,wait_timeout 設(shè)置在120s內(nèi)應(yīng)該是夠用啦,那么相對(duì)應(yīng)的c3p0中 設(shè)置小于wait_timeout 的時(shí)間有效性檢查 -就能確保獲取到連接是有效的。
總結(jié)
以上是生活随笔為你收集整理的mysql超经典的8小时问题-wait_timeout的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机网络面试题整理
- 下一篇: wait_timeout【Mysql】解