使用mysql的長連接


 

 

 

有個資料看得我雲里霧里的。現在用自己的言語來總結一下,寫文字,能夠加深自己的理解。也會在寫的過程中幫助自己發現理解方面瑕疵,繼續查資料求證。

 

 

短鏈接的缺點:創建一個連接,程序執行完畢后,就會自動斷掉與mysqlserver的鏈接。於是多少次php執行,就會多少次這樣的創建和釋放過程。頻繁地創建和釋放連接,比較耗費cpu資源。

 

長連接就可以避免每次請求都創建連接的開銷,節省了時間和IO消耗。

 

長連接是提高了性能。不過還有一些細節的問題需要解決,即mysql發現一個鏈接長時間沒有執行查詢請求,就會自動斷掉這個連接。

 

具體多長時間后斷掉,有個timeout設置時間。通過sql:"show global variables like '%timeout';" 查看。

 

my.conf中的

wait_timeout=2880000
interactive_timeout = 2880000

 

當鏈接已經失效了,仍然去執行查詢操作,一個明顯的表現形式就是提示:MySQL server has gone away

 

啟發:MySQL server has gone away這個信息是mysql服務器提示出來的呢?還是php的mysql擴展提示出來的呢?

 

據判斷,肯定是應用程序服務器報出來的(php)。想一想,如果mysql都已經接到請求了,那么還出現什么鏈接不上。明明都已經鏈接上了。

 

既然mysql服務器都能夠接受請求,那么還怎么處理不過來呢。

 

我們去百度搜索:MySQL server has gone away。從來沒有看到java鏈接mysql出現這樣的情況。如果是mysql 服務器報出來的。那么應該與應用程序無關。所以應該也會搜索到相關信息的。

據此判斷,這是php拋出來的信息。php鏈接不上mysql了。

 

 

 

 

 

http://ronaldbradford.com/blog/sqlstatehy000-general-error-2006-mysql-server-has-gone-away-2013-01-02/

 

使用mysql_ping()函數能夠檢測與mysql服務器是不是鏈接狀態。避免出現MySQL server has gone away。

 

每次執行查詢前,先使用mysql_ping()去檢測一下連接有沒有斷掉。如果斷掉了。重新建立一次鏈接。

具體代碼為:

 

if(mysql_ping()!=0){

 //鏈接已經斷開,需要重新建立鏈接

    $this->conn = mysql_connect($ip,$user_name,$password);

}

 

小缺點是:每次都要去檢測執行mysql_ping(),耗費資源。

 

一種改進辦法是:根據mysql_query()的返回錯誤碼來決定是不是要重新鏈接

 

$res = mysql_query($sql, $this->conn);

       

if($res===false){

 if(mysql_errno($this->conn)==2006 || mysql_errno($this->conn)==2003){

    //去檢測一下與mysql服務器的鏈接是不是有效

    if(mysql_ping()!=0){

       //重新建立鏈接

 

   }

}

}

 

備注:

  2003對應的錯誤信息是,Can't connect to MySQL

 

2006 對應的錯誤信息是 MySQL server has gone away


思考:真正意義上自己實現的連接池,是長期與數據庫服務器鏈接起鏈接的。如何建立起鏈接呢。就是定期發送心跳包。通過心跳包與服務器進行通信。

如果沒有發送心跳包,則會被數據庫服務器斷掉這個鏈接。因為長時間沒有通信的鏈接,要斷掉。


待完善


MYSQL has gone away的解釋:

http://database.51cto.com/art/201105/261107.htm


免責聲明!

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



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