現象
- 設備 (UAG/Scanner) Telnet MySQL 3306,**等待 10 秒** 才收到 Banner
- Linux VM / Windows 同網段 Telnet,**秒回**
- 自寫 C 客戶端 `recv()` 耗時 19.5 秒 (設備) vs 10.5 秒 (VM)
封包分析發現
設備連線後,MySQL Server 發送大量 **NBNS (NetBIOS Name Service)** 查詢封包,嘗試解析客戶端主機名,**直到超時才發送 Banner**。
根因
MySQL 預設啟用 **DNS 反向解析**:收到連線 → 取 Client IP → 反查 PTR 記錄 → 用主機名比對 `mysql.user` 權限。若 DNS 失敗/超時,連線卡住。
解決:關閉反向解析
[mysqld]
skip-name-resolve
Windows (`my.ini`) 與 Linux (`my.cnf`) 同樣有效。修改後**重啟 MySQL**。
驗證結果
| 客戶端 | 修改前 | 修改後 |
| 設備 Telnet | ~10 秒 | 秒回 |
| 設備 C 客戶端 recv | 19.5 秒 | 10.5 秒 (與 VM 持平) |
| VM Telnet | 秒回 | 秒回 (無變化) |
副作用與對策
| 影響 | 說明 | 對策 |
| 無法使用主機名授權 | `GRANT ... TO 'user'@'hostname'` 失效 | **一律用 IP 或 `%` 授權**,更安全、效能更好 |
| 日誌顯示 IP 而非主機名 | General Log / Error Log 的 Host 欄位 | 可接受,IP 更便於追蹤 |
補充:關閉 Named Pipes (Windows)
部分舊版 MySQL 在 Windows 預設啟用 Named Pipes,亦會導致 NBNS 洪水。`my.ini` 加入:
[mysqld]
skip-name-resolve
skip-named-pipe
結語
**`skip-name-resolve` 是 MySQL 遠程連線延遲的「銀彈」**。除非極少數需主機名授權的舊系統,生產環境**強烈建議預設開啟**,配合 IP 白名單授權,兼顧效能與安全。
- 上一篇文章: MySQL 無法連線排查實戰:PHP 執行逾時、TCP 連線耗盡與註冊表調優
- 下一篇文章: 用 MySQL Slow Log 定位 CPU 100% 罪魁禍首:開啟、分析與優化閉環
Copyright ©
程式碼之家 All Rights Reserved