首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

徹底解決MySQL Server has gone away:配置優化與代碼級重連機制

     編輯:MySQL 資料庫相關知識

錯誤成因核心

MySQL Server has gone away本質是連接被服務端主動斷開,最常見兩大場景:

  1. 長耗時操作超過wait_timeout:如PHP采集腳本抓取慢頁面,超過默認8小時(或自定義值)無交互,連接被殺
  2. SQL包過大超過max_allowed_packet:含BLOB/長文本的INSERT/UPDATE,默認1MB限制

方案一:配置層面調大閾值(治標)

編輯my.cnf/my.ini:

[mysqld]
wait_timeout = 2880000          # 33天,實質永不超時
interactive_timeout = 2880000
max_allowed_packet = 100M       # 按業務最大包調整,建議≥10M

或運行時動態設置(需SUPER權限):

SET GLOBAL wait_timeout=2880000;
SET GLOBAL max_allowed_packet=100*1024*1024;

方案二:代碼層面主動心跳重連(治本,推薦)

PHP中封裝ping()方法,執行長任務前調用:

function ping() {
    if (!mysql_ping($this->link)) {
        mysql_close($this->link);              // 關鍵:必須先關閉舊連接
        $this->connect(...);                   // 重新建立連接
    }
}

// 業務調用示例
for ($i=0; $i<10; $i++) {
    $str = file_get_contents('https://slow-site.com');  // 耗時操作
}
$db->ping();                                    // 檢查並重連
$db->query('SELECT * FROM table');              // 安全執行

核心細節:mysql_ping檢測斷開後,必須先mysql_close再重連,否則PHP 5.x+下新連接句柄可能不可用(舊環境mysql_connect直接覆蓋即可)。

官方文檔補充成因清單

  • KILL語句/管理員殺進程
  • 邏輯錯誤:連接關閉後仍發查詢
  • 客戶端權限不足/防火牆攔截3306
  • TCP層讀寫超時(MYSQL_OPT_READ/WRITE_TIMEOUT)
  • 服務端超時且客戶端reconnect=0(默認關閉)
  • Windows下TCP寫入無報錯、讀取才報錯的特殊行為
  • 錯誤/過大查詢包導致服務端主動斷開
  • 客戶端/服務端版本不匹配(4.0.8前後16MB邊界)
  • DNS解析失敗偽裝成網絡超時
  • --skip-networking或防火牆封鎖3306
  • fork子進程共享同一連接(需各自獨立連接)
  • Server執行查詢時Crash(罕見Bug)

最佳實踐總結

  1. 配置層面:wait_timeout設大、max_allowed_packet設夠
  2. 代碼層面:長任務前ping()主動重連,mysql_close後mysql_connect
  3. 架構層面:避免超長事務、大包拆分、子進程獨立連接

雙管齊下,徹底告別gone away。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved