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

MySQL 遠程連線 "Lost connection during query" 根因:glibc gethostbyaddr 緩衝區溢位

     編輯:MySQL 資料庫相關知識

錯誤現象

mysql -h mysql.test.com -u beginner -p
ERROR 2013: Lost connection to MySQL server during query

甚至 mysql -h mysql.test.com 即報錯,尚未進入驗證階段。

根因分析

  1. MySQL 啟動時啟用 skip_name_resolve=OFF(預設)
  2. 客戶端連線觸發 ip_to_hostname() → gethostbyaddr() → _nss_dns_gethostbyaddr_r()
  3. 舊版 glibc(如 2.2.x~2.3.x)該函數存在緩衝區溢位,處理大型 DNS 回應時導致 mysqld 進程 Segfault
  4. 伺服器進程崩潰,客戶端收到連線重置
  5. 解決方案(按推薦順序)

    1. 升級 glibc:yum update glibc / apt-get install libc6 至修復版本(≥ 2.3.4)
    2. 關閉 DNS 反解(最快臨時方案):
      [mysqld]
      skip_name_resolve = ON

      效果:GRANT / SHOW PROCESSLIST Host 欄顯示 IP 而非主機名,需將權限表 Host 改為 IP 或 %。

    3. 調整 nsswitch.conf:
      # /etc/nsswitch.conf
      hosts: files dns  # 移除 myhostname 或調整順序

    驗證步驟

    # 1. 確認 mysqld 進程存活
    ps aux | grep mysqld
    
    # 2. 測試反解
    getent hosts 
    
    # 3. 觀察錯誤日誌
    tail -f /var/log/mysql/error.log
    # 關鍵字:Segmentation fault, gethostbyaddr

    現代版本補充

    • MySQL 5.7+ 預設 skip_name_resolve=ON(部分發布版)
    • MySQL 8.0 引入 host_cache_size 控制快取行為
    • Docker/雲環境建議直接關閉反解,依賴 IP 白名單或 VPC 安全組
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved