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

MySQL 启动卡在 Resolving host... 时该关什么
这是典型 DNS 反向解析阻塞,skip-name-resolve 就是解药。它让 MySQL 跳过对客户端 IP 做 gethostbyaddr() 的过程,直接用 IP 地址做权限匹配。
常见错误现象:
• 启动日志卡在 Starting MySQL... [ OK ] 却无响应
• mysql -h 192.168.1.100 -u root -p 连不上,但 localhost 可以
• 错误日志反复出现 Aborted connection ... because of host name resolution failure
- 只在
my.cnf的[mysqld]段加一行:skip-name-resolve,别写错成skip_name_resolve(下划线无效) - 加完必须重启 MySQL,
systemctl restart mysqld或service mysql restart - 开启后,所有
GRANT语句里的HOST值只能是 IP 或%,不能再用域名(比如'user'@'web01.example.com'会失效)
为什么不能只靠 /etc/hosts 临时解决
/etc/hosts 确实能加速单机解析,但它治标不治本——只要 MySQL 没关 skip-name-resolve,它就仍会调用系统 DNS 接口,而一旦网络 DNS 不可用、超时或返回 NXDOMAIN,连接就会卡住或拒绝。
- 内网环境常有 DNS 服务未部署或配置错误,
ping web01成功不代表 MySQL 解析成功(MySQL 用的是反向解析,查 PTR 记录) -
/etc/hosts无法覆盖所有客户端 IP,尤其容器或云主机 IP 动态分配时 - 某些发行版(如 CentOS Stream 9)默认启用
systemd-resolved,和 MySQL 解析逻辑存在竞态,比单纯 DNS 失败更难排查
skip-name-resolve 开启后权限怎么配才不翻车
原来用域名授权的账号会立即失效,必须重刷权限表。这不是 bug,是设计使然:关闭解析后,MySQL 根本不查域名,只认 IP 字符串。
- 检查现有授权:
SELECT User, Host FROM mysql.user;,把含域名的Host全记下来 - 批量转 IP:比如原为
'app'@'api-prod-01',先nslookup api-prod-01拿到 IP,再执行GRANT ... ON *.* TO 'app'@'10.10.20.5' - 若需兼容多 IP 或动态环境,统一改用
'app'@'%',但务必配合防火墙限制真实可连 IP 段 - 改完运行
FLUSH PRIVILEGES;,别漏掉这步
云环境或 Docker 下还要注意这个点
容器网络或云 VPC 内,客户端 IP 经常是 NAT 后的地址(比如所有请求都显示为 172.17.0.1),这时即使开了 skip-name-resolve,权限控制粒度也会变粗。
- Docker 默认 bridge 网络里,宿主机连容器 MySQL,来源 IP 是
172.17.0.1,不是宿主机真实 IP - 阿里云 RDS 或 AWS RDS 不允许改
my.cnf,也没法开skip-name-resolve,得靠安全组 + 白名单 IP 控制访问 - Kubernetes Pod 间通信若走 ClusterIP Service,MySQL 看到的 client IP 是 kube-proxy 的,不是原始 Pod IP——除非用
externalTrafficPolicy: Local并直连 NodePort
真正麻烦的从来不是加一行配置,而是授权模型得跟着解析方式一起重想。IP 不稳定、NAT 层级多、容器编排抽象强——这些地方绕开 DNS 解析只是第一步,后面权限映射才是硬骨头。










