MySQL DNS 反解析導致連線緩慢:skip-name-resolve 參數完整解析與實驗驗證
錯誤日誌出現 `IP address 'x.x.x.x' could not be resolved: Name or service not known`、大量 `unauthenticated user` 連線堆積,核心原因是 MySQL 預設對客戶端 IP 執行 DNS 反向解析。`skip-name-resolve` 參數可徹底禁用此行為。
問題現象
[Warning] IP address '192.168.1.10' could not be resolved: Name or service not known
[Warning] IP address '192.168.1.14' could not be resolved: Name or service not known
mysql> SHOW PROCESSLIST;
+-----+--------------------+-----------------+------+---------+------+-------+------+
| Id | User | Host | db | Command | Time | State | Info |
+-----+--------------------+-----------------+------+---------+------+-------+------+
| 592 | unauthenticated user | 192.168.1.10:35320 | NULL | Connect | 123 | login | NULL |
| 593 | unauthenticated user | 192.168.1.14:35321 | NULL | Connect | 122 | login | NULL |
根因:MySQL 連線建立流程中的 DNS 反解析
- 新連線到達,產生執行緒處理
- 檢查 Host Cache (主機名快取)
- 未命中 → 執行 `gethostbyaddr(IP)` 解析主機名
- 再執行 `gethostbyname(hostname)` 驗證 IP 一致性
- 無 DNS 伺服器 / /etc/hosts 無對應 → 解析阻塞/超時
- 連線處於 `login` 狀態堆積,佔用執行緒資源
解決方案:啟用 skip-name-resolve
# 修改配置檔
vi /etc/my.cnf
# [mysqld] 區段新增:
skip-name-resolve
# 重啟生效
systemctl restart mysqld
啟用後的影響與注意事項
| 影響 | 說明 | 應對 |
| 授權表 Host 欄位 | 不能使用主機名,只能用 IP 或 % | 建立用戶用 IP: `CREATE USER 'u'@'192.168.1.%'` |
| SHOW PROCESSLIST | Host 欄顯示 IP,不再顯示主機名 | 正常現象 |
| 主從複寫 | CHANGE MASTER TO MASTER_HOST= 不能用主機名 | 用 IP 地址 |
| 效能提升 | 連線建立無 DNS 等待,高併發顯著改善 | 核心收益 |
替代方案:完善 /etc/hosts 或 DNS
# /etc/hosts 新增對應
192.168.1.10 app-server-01
192.168.1.14 app-server-02
# 刷新快取
mysql> FLUSH HOSTS;
實驗驗證關鍵發現:MySQL 解析 `/etc/hosts` 時,同一 IP 只取第一個主機名對應,後續同 IP 的其他主機名被忽略。
相關參數補充
| 參數 | 作用 |
| skip-host-cache | 禁用主機名快取,每次連線都解析 |
| flush hosts | 手動清理主機名快取 |
| skip-networking | 禁用 TCP/IP,只允許 Socket/Named Pipe 連線 |
適用環境判斷
- ✅ 內網環境、無 DNS 伺服器、大量短連線應用 → **強烈建議啟用**
- ✅ 雲端環境 (VPC 內網 IP 固定) → **建議啟用**
- ❌ 需要主機名授權、跨網段複雜拓撲 → 謹慎評估
- ❌ 現有授權表大量使用主機名 → 需遷移授權規則後再啟用
驗證生效
mysql> SHOW VARIABLES LIKE 'skip_name_resolve';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| skip_name_resolve | ON |
+-------------------+-------+
# 連線測試應無 "unauthenticated user" 堆積
mysql> SHOW PROCESSLIST;
- 上一篇文章: MySQL 匯入匯出命令大全:mysqldump、SELECT INTO OUTFILE、LOAD DATA INFILE
- 下一篇文章: MySQL 常見錯誤彙總與解決方案:DNS 反解、執行緒耗盡、Drop Database 失敗、匯入緩慢
Copyright ©
程式碼之家 All Rights Reserved