90%的迁移后连接超时是skip-name-resolve配置启用或未同步导致权限匹配失效;需用show processlist和strace验证dns反查,确认配置在[mysqld]段、重启生效,并将mysql.user中域名host更新为ip后flush privileges。

直接结论:90% 的迁移后连接超时,不是网络问题,而是 skip-name-resolve 配置被意外启用或未同步导致的权限匹配失效。
确认是不是 DNS 反查卡住的
别靠猜,用两个低成本方式快速验证:
- 在 MySQL 服务端执行
SHOW PROCESSLIST;,看新连接是否长期卡在unauthenticated user或Connecting to master状态 - 用
strace -p $(pgrep mysqld) -e trace=connect,gethostbyaddr抓系统调用,如果反复看到失败或超时的gethostbyaddr调用,就是它 - 临时停掉服务端 DNS 解析服务(如
sudo systemctl stop systemd-resolved),再连一次;如果秒通,基本锁定
检查 skip-name-resolve 是否已启用且生效
这个参数只在服务端 [mysqld] 段起作用,加在客户端配置或 [client] 段完全无效。常见踩坑点:
免费 DNS 与邮件安全分析(IntoDNS.ai):包括 DNSSEC、SPF、DKIM、DMARC、MTA-STS、BIMI、SMTP STARTTLS、FCrDNS、黑名单、发件人要求及报告。
- 改错了配置文件路径:Ubuntu/Debian 下常被
!includedir /etc/mysql/conf.d/覆盖,用mysqld --verbose --help | grep "Default options"确认最终加载路径 - 没真正重启:
systemctl reload mysql不会重载该参数,必须systemctl restart mysql - Windows 默认已启用,Linux 发行版包(APT/YUM 安装)默认关闭——别假设它已经开了
- 正确写法只有一行:
skip-name-resolve(值不写=ON或=1更稳妥,MySQL 5.7+ 支持无值写法)
修复因跳过 DNS 导致的权限失效
启用 skip-name-resolve 后,MySQL 完全按 IP 匹配 mysql.user.Host 字段,所有带域名的授权(如 'app'@'web01.example.com')立即失效。
- 先查问题账号:
SELECT User, Host FROM mysql.user WHERE Host NOT IN ('%', 'localhost', '127.0.0.1', '::1'); - 逐条更新为实际客户端 IP:
UPDATE mysql.user SET Host = '10.0.2.5' WHERE User = 'app' AND Host = 'web01.example.com'; - 刷新权限:
FLUSH PRIVILEGES; - 注意:Kubernetes 等动态 IP 环境慎用硬写 IP,应评估是否真能关反查;若不能,优先修 DNS 延迟而非硬切
不关反查,还能怎么压低延迟?
这是“治标”方案,但有时比改权限更现实:
- 确保 MySQL 服务器的
/etc/resolv.conf只写可信、低延迟 DNS(如内网 CoreDNS 或127.0.0.53),删掉公共 DNS(如8.8.8.8) - 客户端连接串里用 IP(如
host=10.0.2.5)而不是域名——这绕过的是客户端本地 DNS 解析,和 MySQL 服务端反查无关,但容易混淆 - 如果应用用域名连接慢,且服务端没开
skip-name-resolve,那问题大概率在客户端解析环节,不是这里要修的
最易被忽略的一点:迁移后往往只同步了数据和用户表,却忘了同步 Host 字段的语义含义变化。一旦启用 skip-name-resolve,Host 就从“可读标识”变成“精确匹配规则”,任何残留的域名授权都会静默失效,报错却是 Access denied for user 'xxx'@'192.168.1.100'——看起来像密码错,其实是匹配不到。










