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

MySQL 「could not be resolved」DNS 反解警告徹底解決:skip-name-resolve 原理與實驗驗證

     編輯:MySQL 資料庫相關知識

問題現象

[Warning] IP address '192.168.1.10' could not be resolved: Name or service not known
SHOW PROCESSLIST 大量:
| 592 | unauthenticated user | 192.168.1.10:35320 | NULL | Connect |   | login | NULL |

核心解決方案

[mysqld]
skip-name-resolve

在 my.cnf [mysqld] 區段加入上述參數並重啟 MySQL,即可禁用 DNS 反解析,消除警告與連線延遲。

深度原理:MySQL 如何使用 DNS

  1. 新連線觸發: 每個新連線由專屬線程處理。
  2. Host Cache 查找: 先檢查內存 host_cache 是否已有 IP→Hostname 映射。
  3. 雙向解析驗證:
    • 正向:gethostbyaddr(IP) → Hostname
    • 反向:gethostbyname(Hostname) → IP
    • 雙向結果一致才認定合法,防止 IP 欺騙。
  4. 執行緒安全:
    • OS 支援 gethostbyaddr_r / gethostbyname_r → 線程安全,並發解析。
    • 不支援 → 全域互斥鎖 LOCK_host_cache,同一時間僅能解析一個 IP,嚴重阻塞高併發連線。
  5. 快取機制: 解析結果存入 host_cache(預設 128 條),後續連線直接命中。

skip-name-resolve 影響範圍

功能啟用前啟用後
權限表 Host 欄支援主機名、IP、通配符僅支援 IP 與 %
連線建立延遲可能阻塞等待 DNS無 DNS 開銷,極快
host_cache正常運作仍存在,但僅存 IP
flush hosts清理快取同樣有效

實驗驗證:/etc/hosts 多主機名映射的解析優先級

# /etc/hosts 內容
192.168.1.1 hostname_online
192.168.1.1 h_tt_1
GRANT USAGE ON *.* TO root@'h_tt_%' IDENTIFIED BY 'root';
FLUSH HOSTS;

連線測試:

mysql -h 192.168.1.1 -uroot -proot
# ERROR 1045: Access denied for user 'root'@'hostname_online'

結論: MySQL 解析 /etc/hosts 時,以 IP 為鍵值,僅採用第一條匹配記錄,後續同 IP 的其他主機名被忽略。此行為在官方文件「How MySQL Uses DNS」中有明確說明。

適用場景建議

  • 內網環境、無 DNS 服務、主機數眾多: 強烈建議啟用 skip-name-resolve,權限表統一用 IP/%。
  • 需保留主機名權限: 必須配置可靠的內部 DNS 或完善 /etc/hosts,並確保每個 IP 僅映射一個主機名(或接受首條優先規則)。
  • 調優手段: --skip-host-cache 禁用快取 / FLUSH HOSTS 手動清理 / 增大 HOST_CACHE_SIZE(需重編譯)。

最佳實務: 現代雲原生/容器化部署中,服務發現通常由 Sidecar/Service Mesh 處理,資料庫權限建議直接使用 CIDR 區段(如 10.0.0.0/8)或 % 搭配強認證(SSL/TLS + 強密碼/憑證),徹底繞開 DNS 解析陷阱。

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