看到大量unauthenticated user即可确定是dns反向解析卡住,mysql调用gethostbyaddr()反解ip失败或超时导致线程卡在login状态;需配置skip-name-resolve=on于[mysqld]段并重启,同时将mysql.user表中非ip/%%的host替换为对应ip或网段。

直接看 SHOW PROCESSLIST 里有没有大量 unauthenticated user,有就基本锁死是 DNS 反向解析卡住。
怎么快速确认是 gethostbyaddr() 在拖慢连接?
MySQL 收到 TCP 连接后,会立即调用 gethostbyaddr() 把客户端 IP 反解成域名。如果 DNS 不通、没配 PTR 记录或超时,线程就卡在 login 状态,不报错也不拒绝,只干等。
- 执行
SHOW PROCESSLIST;,观察新连接的State列是否长期停留在Connecting to master或空状态,Host列显示的是 IP(如10.20.30.40:54321)而非域名 - 用
strace -p $(pgrep mysqld) -e trace=gethostbyaddr挂着,然后从另一台机器连一下,看是否卡在该系统调用上 - 临时停掉本机 DNS:Linux 上运行
sudo systemctl stop systemd-resolved,再试连;Windows 上禁用 DNS 客户端服务。秒连即证实问题 - 对比
mysql -h ::1 -u root -p(IPv6 回环)和mysql -h 127.0.0.1 -u root -p,若前者快后者慢,说明 IPv4 反查阻塞
skip-name-resolve=ON 为什么加了也不生效?
这个参数极其挑剔——写错位置、没重启、被覆盖,都会让它形同虚设。
免费 DNS 与邮件安全分析(IntoDNS.ai):包括 DNSSEC、SPF、DKIM、DMARC、MTA-STS、BIMI、SMTP STARTTLS、FCrDNS、黑名单、发件人要求及报告。
- 必须写在
[mysqld]段内,[client]、[mysql]或配置文件开头都无效 - 必须完整重启:
systemctl restart mysql,reload不重载该参数 - Ubuntu/Debian 用户注意:
!includedir /etc/mysql/conf.d/下的其他 .cnf 文件可能覆盖主配置,先运行mysqld --verbose --help | grep "Default options"确认最终加载路径 - 验证是否真生效:
mysql -e "SHOW VARIABLES LIKE 'skip_name_resolve';"返回ON才算成功,别只改配置就以为完事
开了 skip-name-resolve 后用户连不上,怎么办?
这不是 bug,是行为变更的必然结果:MySQL 彻底跳过 DNS 解析后,mysql.user 表里的 Host 字段只能按字面匹配 IP 或 %,所有域名授权全部失效。
- 典型现象:
Access denied for user 'app'@'192.168.1.100',但SELECT User, Host FROM mysql.user显示的是'app'@'web01.example.com' - 查问题账号:
SELECT User, Host FROM mysql.user WHERE Host NOT IN ('%', 'localhost', '127.0.0.1', '::1') AND Host NOT REGEXP '^\d+\.\d+\.\d+\.\d+$'; - 修复方式:把域名改成对应 IP,例如
UPDATE mysql.user SET Host = '192.168.1.100' WHERE User = 'app' AND Host = 'web01.example.com'; FLUSH PRIVILEGES; - 注意:本地用
localhost能连,换成127.0.0.1就拒绝——这是权限粒度变化的明确信号,'root'@'localhost'和'root'@'127.0.0.1'是两个独立账户
最常被忽略的一点:skip-name-resolve 只解决服务端反查,不解决客户端侧的 DNS 解析(比如应用连接串里写 host=database-prod)。那部分延迟得另查 /etc/resolv.conf 或应用 DNS 配置。










