MySQL连接卡在“Connecting to localhost…”阶段90%是服务端反向DNS解析阻塞;可通过停DNS服务(sudo systemctl stop systemd-resolved)或换IPv6回环(mysql -h ::1)快速验证,确认后须在[mysqld]段配置skip-name-resolve=ON并重启,同时将mysql.user表中域名授权改为IP或%。

MySQL连接卡在“Connecting to localhost…”阶段,90%是服务端反向DNS解析阻塞,不是密码错、不是网络抖动,必须改mysqld配置并重启,否则所有客户端侧操作都是绕路。
怎么确认真是反向DNS解析卡住的?
别靠猜,用两个低成本方式快速锁定:
- 临时停掉本机 DNS 服务:
sudo systemctl stop systemd-resolved,再执行mysql -h 127.0.0.1 -u root -p;如果秒进,基本坐实 - 换 IPv6 回环测试:
mysql -h ::1 -u root -p;若 IPv4 卡顿但 IPv6 立即响应,说明是 IPv4 的gethostbyaddr()反查阻塞 - 查运行时状态:
SELECT Host FROM information_schema.PROCESSLIST WHERE Command = 'Connect';—— 如果长期显示10.0.2.5:52183这类 IP+端口,且从不出现web01.example.com,说明解析已被跳过;反之则还在查
skip-name-resolve 必须加在 [mysqld] 段并重启才生效
这个参数只对 MySQL 服务端起作用,写在 [client]、[mysql] 或配置文件开头都无效。常见失效原因:
- 改错了文件:Ubuntu/Debian 下
!includedir /etc/mysql/conf.d/可能覆盖主配置,先运行mysqld --verbose --help | grep "Default options"确认最终加载路径 - 没真正重启:用
systemctl reload mysql不生效,必须systemctl restart mysql(或mysqld) - Windows 用户容易误配到
my.ini全局区,要确保写在[mysqld]段内 - 正确写法(在
/etc/mysql/mysql.conf.d/mysqld.cnf或/etc/my.cnf中):
[mysqld] skip-name-resolve = ON
生效后验证:mysql -e "SHOW VARIABLES LIKE 'skip_name_resolve';" 返回 ON 才算成功。
开了 skip-name-resolve 后权限匹配全挂了?这是设计使然
启用后,MySQL 彻底跳过所有客户端 IP 的反向 DNS 解析,user@host 中的 host 字段只能匹配 IP 或 %,不再识别 localhost、web01.example.com 这类域名或别名。典型表现:
-
GRANT ALL ON *.* TO 'root'@'localhost'→ 用mysql -h 127.0.0.1连直接报Access denied -
SELECT User, Host FROM mysql.user WHERE Host NOT IN ('%', '127.0.0.1', '::1', 'localhost');能揪出所有高危账号 - 必须逐条更新:
UPDATE mysql.user SET Host = '10.0.2.5' WHERE User = 'app' AND Host = 'web01.example.com'; - 最后别忘
FLUSH PRIVILEGES;
Kubernetes 等动态 IP 环境慎用——Pod IP 随时变,硬写 IP 不可持续,此时应评估是否真能关反查。
客户端用域名连得慢?skip-name-resolve 完全不管这事
如果应用连接串里是 host=database-prod,那慢的是客户端本地 getaddrinfo() 正向 DNS 解析,不是服务端反查。解决方向完全不同:
- 检查客户端
/etc/resolv.conf或 DNS 配置 - 在客户端
/etc/hosts里加10.0.2.5 database-prod可绕过 - 验证方式:
time nslookup database-prod或time host database-prod,耗时高就说明是客户端 DNS 问题
最常被忽略的点:开了 skip-name-resolve 后,information_schema.PROCESSLIST 的 Host 列会永远只显示 IP,但你如果还留着 'app'@'web01.example.com' 这种账号,它就永远匹配不上——这不是 bug,是机制切换后的必然结果,必须手动清理或转换。


















