萬盛學電腦網

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

MySQL「Lost connection at reading initial communication packet」兩大核心修復

錯誤完整訊息

Lost connection to MySQL server at 'reading initial communication packet'
system error: 0

成因一:innodb_buffer_pool_size` 設定過大超過實體記憶體

現象:配置檔設定 innodb_buffer_pool_size = 2048M,但伺服器實體記憶體僅 4G(或容器限制 2G),導致啟動時無法分配共享記憶體,MySQL 異常退出,客戶端收到「初始通訊封包讀取失敗」。

修正原則

  • 專用 DB 伺服器:innodb_buffer_pool_size ≈ 物理記憶體 × 60~75%
  • 共用/容器環境:≈ 可用記憶體 × 50~60%
  • 4G 記憶體建議:1G~1.5G(1024M~1536M)
  • 16G 記憶體建議:10G~12G

修改範例

# /etc/my.cnf
[mysqld]
innodb_buffer_pool_size = 1024M
# 或依實際記憶體調整
innodb_buffer_pool_size = 12G

修改後 systemctl restart mysqld。

成因二:DNS 反解析超時(skip-name-resolve 缺失)

MySQL 預設對連入連線執行「反向 DNS 解析」(IP → 主機名),若 DNS 伺服器無回應或極慢,握手階段逾時,客戶端收到同樣錯誤。

即時緩解(動態生效)

mysql -e "SET GLOBAL skip_name_resolve=ON;"

永久修正

# /etc/my.cnf
[mysqld]
skip-name-resolve

副作用: 啟用後,mysql.user 授權表 Host 欄不再支援主機名,僅能用 IP、CIDR、%、localhost。請先確認所有帳號授權均為 IP 格式。

排查清單(依序執行)

  1. free -h 確認實體記憶體與 innodb_buffer_pool_size 關係。
  2. tail -f /var/log/mysqld.log 觀察啟動日誌是否有 InnoDB: Cannot allocate memory。
  3. 檢查 skip-name-resolve 是否已設定。
  4. netstat -tlnp | grep 3306 確認埠口正常監聽。
  5. 客戶端改用 IP 直連測試:mysql -h 127.0.0.1 -u root -p。
  6. 若仍失敗,檢查 bind-address、防火牆、SELinux/AppArmor。

容器化環境額外注意

  • Docker --memory 限制 < innodb_buffer_pool_size 會導致 OOM Kill,容器直接消失,客戶端同樣報此錯誤。
  • 建議在容器啟動腳本中動態計算:innodb_buffer_pool_size=$(awk '/MemTotal/ {print int($2*0.6/1024)"M"}' /proc/meminfo)。
copyright © 萬盛學電腦網 all rights reserved