萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL "Server has gone away" 錯誤原因深度解析與解決方案

錯誤現象

數據導入腳本運行中拋出 MySQL server has gone away,但數據庫服務進程仍在運行,其他查詢正常。

核心原因:SQL 語句過長超過 max_allowed_packet

默認 max_allowed_packet=4MB,若單條 SQL 超過此限制,服務端會斷開連接,客戶端收到此錯誤。

代碼排查實錄

問題代碼片段

while ($rs = mysql_fetch_array($query)) {
    $os = autoaddlink($os);  // 內部執行 SELECT 查詢並構建極長字符串
    INSERT ...;              // 將構建的超長字符串寫入
}

autoaddlink() 內部循環查詢並不斷拼接字符串,導致最終 INSERT 語句極長。

根因分析:變量生命周期導致字符串疊加

$tmpstr 在函數內部循環中持續拼接,每次調用 autoaddlink 都在上次結果基礎上疊加,而非重置。放入 while 循環後,字符串指數級增長,最終超過 max_allowed_packet。

解決方案

  1. 修正變量作用域:在函數內部初始化 $tmpstr = ''; 確保每次調用重置。
  2. 調大 max_allowed_packet:my.cnf 中設置 max_allowed_packet=64M(或更大),重啟生效。
  3. 分批提交:避免單次構建超大 SQL,改用批量插入或事務分批提交。
  4. 使用預處理語句:參數化綁定,避免巨大 SQL 文本傳輸。

其他常見觸發場景

  • 長連接超時(wait_timeout/interactive_timeout)導致連接被服務端主動斷開。
  • 客戶端發送數據包過大(如大 BLOB/TEXT 寫入)。
  • 服務端 OOM Killer 殺掉進程(錯誤日志會有 Out of memory 記錄)。

排查檢查清單

  1. 檢查錯誤日志 .err 確認具體錯誤碼。
  2. 執行 SHOW VARIABLES LIKE 'max_allowed_packet'; 確認當前值。
  3. 檢查應用是否使用長連接且未處理重連邏輯。
  4. 抓包分析(tcpdump)確認斷開時雙方交互。
copyright © 萬盛學電腦網 all rights reserved