是DNS反向解析导致连接卡顿;表现为SHOW PROCESSLIST中大量unauthenticated user、telnet通但连接慢,且SELECT @@skip_name_resolve返回0,strace可见gethostbyaddr阻塞。

确认是不是 DNS 反向解析在卡连接
别急着改配置,先验证问题根源。MySQL 卡在 Connecting to... 阶段,但 ping 通、telnet host 3306 也秒通,基本就是它了。更直接的证据:
-
SHOW PROCESSLIST;里大量状态为unauthenticated user或长期卡在Connecting to master - 执行
SELECT @@skip_name_resolve;,返回0表示未关闭反查 - 用
strace -p $(pgrep mysqld) -e trace=gethostbyaddr观察是否反复阻塞在该系统调用 - 临时停 DNS 服务:
sudo systemctl stop systemd-resolved,再连mysql -h 127.0.0.1 -u root -p;若从几秒变秒进,就坐实了
正确启用 skip-name-resolve=ON
这个参数只在服务端生效,且必须写对位置、重启才起作用——写错地方或只 reload 等于没做。
- 编辑 MySQL 配置文件(Linux 常见路径:
/etc/my.cnf、/etc/mysql/mysql.conf.d/mysqld.cnf;Windows 是安装目录下的my.ini) - 确保加在
[mysqld]段内,不是[client]或文件开头:[[mysqld]]<br>skip-name-resolve = ON
- Ubuntu/Debian 用户注意:
!includedir /etc/mysql/conf.d/可能覆盖主配置,用mysqld --verbose --help | grep "Default options"确认最终加载路径 - 必须重启服务:
sudo systemctl restart mysql(reload不生效) - 验证是否成功:
mysql -e "SHOW VARIABLES LIKE 'skip_name_resolve';"返回ON才算到位
skip-name-resolve=ON 后连不上?权限 Host 写错了
启用后 MySQL 彻底跳过 DNS 解析,mysql.user 表里的 Host 字段只能按字面匹配 IP 或 %,所有带域名的授权全部失效——这不是 bug,是行为变更的必然结果。
- 典型报错:
Access denied for user 'app'@'192.168.1.100',但SELECT User, Host FROM mysql.user;显示的是'app'@'web01.example.com' - 本地用
localhost能连,换成127.0.0.1就拒绝,就是权限粒度变化的明确信号 - 批量检查问题账号:
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 = '10.20.30.40' WHERE User = 'app' AND Host = 'web01.example.com'; FLUSH PRIVILEGES; - Kubernetes 等动态 IP 场景慎用硬写 IP,应评估是否真需要关掉反查,或改用
%+ 网络层隔离
不开 skip-name-resolve 的临时缓解手段
如果暂时不能改配置(比如生产环境审批流程长),可先压低延迟,但只是治标:
- 强制走 IPv6 回环测试:
mysql -h ::1 -u root -p,若比127.0.0.1快,说明 IPv4 反查被卡住 - 缩短 glibc DNS 超时:在
/etc/resolv.conf加options timeout:1 attempts:2,避免默认 5 秒 × 3 次重试 - 检查
/etc/hosts是否缺失本机映射,补上127.0.0.1 localhost和对应主机名 - 客户端连库时加
-A(即--disable-auto-rehash),避免元数据拉取拖慢首次交互
Access denied。这一步漏掉,问题就从“慢”变成“不可用”。


















