首頁  >  文章  >  資料庫  >  PHP程式mysql報錯mysql has gone away

PHP程式mysql報錯mysql has gone away

小云云
小云云原創
2018-03-14 15:49:033590瀏覽


本文主要和大家分享常駐記憶體的PHP程式mysql報錯mysql has gone away,在cli環境下,PHP程式需要長時間運行,客戶端與MySQL伺服器之間的TCP連線是不穩定的。

不穩定的原因有以下可能:

  • MySQL-Server會在一定時間內自動切斷連線

  • ##PHP程式遇到空閒期時長時間沒有MySQL查詢,MySQL-Server也會切斷連接回收資源

  • #其他情況,在MySQL伺服器中執行kill process殺掉某個連接,MySQL伺服器重啟

  • 網路抖動

這時PHP程式中的MySQL連線就失效了。如果還是執行mysql_query,就會報一個

MySQL server has gone away的錯誤。程式處理不到就直接遇到致命錯誤並退出了。所以PHP程序中需要斷線重連。

解決方案

mysql_ping

有很多人提出了

mysql_ping的方案,每次mysql_query進行連接偵測或定時連接檢測。

這個方案不是最好的。原因是:

mysql_ping需要主動偵測連接,帶來了額外的消耗。定時執行mysql_ping無法解決問題,如剛剛執行過mysql_ping檢測之後,連接就關閉了;

捕獲錯誤碼,進行斷線重連

它的原理是:

mysql_query執行後檢測回傳值,如果mysql_query回傳失敗,偵測錯誤碼發現為2006/2013(這2個錯誤表示連接失敗),再執行一次mysql_connect執行mysql_connect後,重新執行mysql_query如果mysql_query後,重新執行mysql_query

如果

mysql_query

回傳成功,那麼連線是有效的,這是一次正常的呼叫。
  • 眾多知名的PHP常駐進程框架

swoole_framework中query方法。
  • $res = mysql_query($sql, $this->conn);if ($res === false)
    {    if (mysql_errno($this->conn) == 2006 or mysql_errno($this->conn) == 2013)
        {        $r = $this->checkConnection();        if ($r === true)
            {
                continue;
            }
        }

workerman中資料庫連接類別execute方法。

  protected function execute($query, $parameters = "")
    {        try {            ...
        } catch (PDOException $e) {
            // 服务端断开时重连一次            if ($e->errorInfo[1] == 2006 || $e->errorInfo[1] == 2013) {
                $this->closeConnection();
                $this->connect();            ...
        }
    }

很明顯捕捉錯誤碼,進行斷線重連,是高可靠低消耗的方案,推薦大家在常駐環境裡使用。

thinkphp + phpworkman 使用TP+workman也會出現類似的情況,TP從V5.0.6+

版本開始,支援Mysql的斷線重連機制,預設關閉,需要的話,在

application/databases.php

資料庫設定檔中加入

// 开启断线重连'break_reconnect' => true,

這樣就OK了。

相關推薦:

###常駐記憶體的PHP程式mysql報錯######

以上是PHP程式mysql報錯mysql has gone away的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn