加skip-name-resolve可解决连接慢和权限匹配失败,但必须同步将mysql.user表中Host字段的域名改为IP或通配符,否则基于域名的授权全部失效。

直接加 skip-name-resolve 能解决连接慢和权限匹配失败,但必须同步改 mysql.user 表里的 Host 字段——否则所有基于域名的授权都会失效。
为什么主机名授权会“突然”不生效
MySQL 默认对每个客户端 IP 做反向 DNS 解析(查 PTR 记录),把 192.168.1.100 尝试转成 web1.internal。如果 DNS 不响应、没配 PTR、或解析结果和 mysql.user 表里写的 Host 值不一致(比如表里是 'app'@'web1',但实际解析成 web1.internal),就匹配失败,降级到 '%' 或直接拒绝。
-
SELECT USER(), CURRENT_USER()两者不一致,基本就是这个原因 - Linux 客户端连 Windows 主机名(如
DESKTOP-ABC123)几乎必挂,因为 MySQL 服务端根本不会去查 Windows 的 NetBIOS 名 - 容器内用服务名(如
mysql)连接,宿主机上跑的客户端却查不到该名——CURRENT_USER()可能变成'app'@'172.18.0.1',而你只授了'app'@'mysql'
加 skip-name-resolve 后权限表怎么改
加完配置后,MySQL 彻底忽略 DNS,只认字面 IP 或通配符。原来靠主机名授权的账号全部失效,必须手动修正:
- 先查哪些用户用了域名:
SELECT User, Host FROM mysql.user WHERE Host NOT IN ('localhost', '%', '127.0.0.1') AND Host NOT LIKE '%.%';(注意:有些 Host 是纯字母,不是域名) - 把域名 Host 改成对应 IP:
UPDATE mysql.user SET Host = '192.168.1.101' WHERE User = 'app' AND Host = 'web1.local'; - 或者改用子网通配:
UPDATE mysql.user SET Host = '192.168.1.%' WHERE User = 'app' AND Host = 'web1.local'; - 改完必须执行:
FLUSH PRIVILEGES;(直改表就必须刷)
不改配置也能临时绕过
如果你不能动生产配置,又急需连上,可以调整客户端行为,避开服务端 DNS 查找环节:
- 本地开发时,别用
localhost,改用127.0.0.1:mysql -h127.0.0.1 -uuser -p—— 这强制走 TCP,且服务端拿到的是明确 IP - Docker Compose 场景下,在应用容器里连
mysql服务名没问题;但若从宿主机调试,得用容器真实 IP(docker inspect myapp | grep IPAddress)或在宿主机/etc/hosts补一行:172.18.0.3 mysql - 应用代码里连接串的
host字段,避免填db.example.com这类需解析的值,优先填内网 IP
最易被忽略的一点:改了 skip-name-resolve 后,localhost 和 127.0.0.1 在权限表里仍是两个独立条目——前者走 socket,后者走 TCP,授权必须都覆盖,否则换一种连接方式就报错。


















