在 MySQL 性能調優的過程中,skip_name_resolve 是一個頻繁被提及的參數。它的核心作用是禁止 MySQL 服務端進行 DNS 域名解析(包含主機名解析)。許多 DBA 都推薦開啟此參數,但背後的運作原理、適用場景以及潛在影響,往往需要更深入的理解才能做出正確決策。
MySQL 服務端在內存中維護一份 Host Cache,專門用於非本地 TCP 連接。該緩存記錄三類信息:客戶端 IP、主機名以及錯誤信息。其設計初衷主要有二:
max_connect_errors 參數實現惡意 IP 的自動封禁,緩解暴力破解攻擊。可通過 performance_schema.host_cache 表查看緩存詳情。
HOST=NULL,HOST_VALIDATED=FALSE。HOST_VALIDATED,若為 FALSE 則嘗試 DNS 解析:
HOST_VALIDATED=TRUE。注意,成功標準不僅是正向解析出主機名,還需反向解析驗證 IP 一致性。HOST=NULL,但設置 HOST_VALIDATED=TRUE,後續不再嘗試解析。HOST_VALIDATED=FALSE,下次連接重試解析。host_cache_size(5.6.8+ 默認基於 max_connections 動態調整)受限,大量客戶端 IP 會導致 LRU 淘汰早期記錄,迫使重新解析。user@hostname)只需一次配置,免去頻繁更新 IP 白名單的麻煩。max_connect_errors(默認 100),自動封鎖連續失敗的 IP,提供基礎防暴力破解能力。將 max_connect_errors 設為 2,通過 telnet 模擬中斷連接兩次,第三次即便使用正確賬號密碼也會報錯:Host 'host_name' is blocked because of many connection errors。此時 host_cache 表中 sum_connect_errors 顯示為 2,host_validated=YES,host=NULL(解析失敗或未解析)。
解封方式:FLUSH HOSTS;、mysqladmin flush-hosts、TRUNCATE performance_schema.host_cache,或等待緩存被淘汰。
設置 skip_name_resolve=ON 後:
mysql.user 表中基於主機名的授權(如 root@mysql-slave1)失效,錯誤日誌記錄 [Warning] 'user' entry 'root@mysql-slave1' ignored in --skip-name-resolve mode.root@192.168.244.144)而非主機名。host_cache_size=0:完全禁用 Host Cache(動態參數,可在線修改)。skip-networking:完全禁用 TCP/IP 連接,僅允許 Socket 本地連接。核心建議:
skip_name_resolve,除非環境確實存在 DNS 故障或極高延遲。保留主機名授權優勢,解耦 IP 變更風險。localhost(Socket)與 127.0.0.1(TCP)均顯示 root@localhost;開啟後 TCP 顯示 root@127.0.0.1。可通過 \s 命令確認當前連接類型。參考資料:
1. Tuicool 文章
2. MySQL 官方文檔 - Host Cache
3. MySQL 官方文檔 - Blocked Host