连接卡在“Checking host”状态是因为MySQL对客户端IP执行DNS反向解析(gethostbyaddr),当DNS响应慢或超时就会阻塞;确认方法是查mysql.user表中含域名的授权记录并结合SHOW PROCESSLIST观察状态。

为什么连接卡在“Checking host”状态?
MySQL客户端连上后,线程状态长期停留在 Checking host,基本就是用户主机匹配规则触发了DNS反向解析。这不是网络不通(ping 和 telnet 都通),而是 MySQL 在调用 gethostbyaddr() 系统函数,试图把客户端IP反解成域名——一旦 DNS 响应慢或超时,每个新连接都会卡住几秒甚至更久。
怎么确认是 host 匹配规则惹的祸?
直接查 mysql.user 表里非标准 host 的记录:
SELECT user, host FROM mysql.user
WHERE host NOT IN ('%', 'localhost', '127.0.0.1')
AND host NOT REGEXP '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$';只要结果不为空,就说明存在基于域名(如 'app'@'web01.example.com')或模糊域名(如 'dev'@'%.corp')的授权,MySQL 就会尝试反解。
再配合 SHOW PROCESSLIST; 观察新连接的状态,如果卡在 Checking host,基本坐实。
skip_name_resolve=ON 后为什么用户登录失败?
开启 skip_name_resolve=ON 后,MySQL 不再做反向解析,只按原始连接 IP 匹配 host 字段。原来存的是域名的授权记录(比如 'api'@'svc-prod.internal'),现在客户端用 10.1.2.3 连,而表里没这条 'api'@'10.1.2.3',自然拒绝。
- 修复方式不是“改配置来回切”,而是批量重建授权:用实际 IP 或 CIDR 段替代域名
- 例如:
GRANT SELECT ON *.* TO 'api'@'10.1.2.0/24';(MySQL 8.0+ 支持 CIDR) - 旧版本只能逐条写:
GRANT SELECT ON *.* TO 'api'@'10.1.2.3'; - 执行完必须
FLUSH PRIVILEGES;
不想改授权,又想绕过 DNS 卡顿怎么办?
临时手段有效,但治标不治本:
- 客户端强制走 IP:
mysql -h 10.1.2.3 -u app -p,避免localhost或域名触发解析 - 检查
/etc/resolv.conf,加options timeout:1 attempts:2缩短 glibc DNS 超时 - 本地
/etc/hosts预埋常用客户端 IP → 域名映射,让反解瞬间返回
这些只是缓冲,真正稳定的做法是统一用 IP/CIDR 授权 + 开 skip_name_resolve=ON。否则每次扩容新机器、换 DNS 服务器,都可能重新掉进这个坑。


















