应关闭 mysql 的 dns 反向解析功能,即在 my.cnf 的 [mysqld] 段添加 skip-name-resolve 并重启服务;开启后需将授权语句中的域名 host 改为 ip 或 %,并执行 flush privileges。

直接关掉 DNS 反向解析,这是最有效、最常用的解法。 出现大量 unauthenticated user 并不是权限或密码错了,而是 MySQL 卡在 IP → 主机名 → IP 的双向 DNS 解析上,线程堆在 login 状态不释放,导致连接慢、查询卡、甚至“假死”。
怎么确认是 DNS 解析卡住?
运行 SHOW PROCESSLIST;,看到一堆 unauthenticated user 且 State 是 login、Host 列显示的是客户端真实 IP(如 192.168.10.5:54321),基本就能锁定。再查变量:
SELECT @@skip_name_resolve;
如果返回 0,说明没开跳过解析;同时检查错误日志里有没有类似 Can't get hostname for your address 或 Aborted connection ... user: 'unauthenticated' 的记录。
配置 skip-name-resolve 必须注意的三件事
这个参数不是加了就生效,容易配错位置或格式:
- 必须写在配置文件的
[mysqld]段下,不能写在[client]或其他段里 - 配置项名是
skip-name-resolve,不是--skip-name-resolve(后者只用于命令行启动) - Linux 下常见路径是
/etc/my.cnf或/etc/mysql/mysql.conf.d/mysqld.cnf;Windows 是my.ini,别改错文件
改完必须重启服务:systemctl restart mysql 或 service mysqld restart,热加载不生效。
开了 skip-name-resolve 后权限语句必须重写
MySQL 不再做主机名解析,所有带域名的授权会失效。比如你原来有:
GRANT ALL ON *.* TO 'app'@'web01.example.com';
现在用该服务器 IP 连接就会被拒绝。必须改成基于 IP 或通配符的授权:
- 单个 IP:
GRANT ALL ON *.* TO 'app'@'192.168.10.5'; - 网段:
GRANT SELECT ON db.t1 TO 'report'@'10.0.2.%'; - 任意 IP(慎用):
GRANT ALL ON *.* TO 'dev'@'%';
特别注意:'root'@'localhost' 和 'root'@'127.0.0.1' 是两个不同账户。开了 skip-name-resolve 后,localhost 走 Unix socket 仍可用,但 127.0.0.1 必须显式创建,否则报错 ERROR 1130 (HY000): Host '127.0.0.1' is not allowed to connect。
真正麻烦的不是加参数,而是授权语句的批量替换和验证——尤其当应用分布在多个子网、用了不同域名连接时,漏掉一个 @'host' 就会导致部分服务连不上。上线前务必逐条核对 SELECT User, Host FROM mysql.user; 输出,并用实际 IP 测试连接。











