使用mysql的長連線

王滔發表於2015-09-10

 

 

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

 

 

短連結的缺點:建立一個連線,程式執行完畢後,就會自動斷掉與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

相關文章