MySQL报错“Unknown MySQL server host”或“Can't get hostname for your address”,根本原因是DNS解析失败:客户端无法将host名解析为IP(查/etc/hosts或DNS失败),或服务端反向解析客户端IP时超时;解决需分两端——客户端确保host可解析(检查/etc/hosts、nsswitch.conf、resolv.conf),服务端建议配置skip-name-resolve并重启,且授权语句中Host须改用IP或%。

MySQL 报错 Unknown MySQL server host 或 Can't get hostname for your address,基本就是 DNS 解析卡在了第一步——连 IP 都没拿到,或者拿错了。
检查 /etc/hosts 是否漏配或写错
MySQL 客户端(比如你代码里的 host: 'mysql')要先查 /etc/hosts,再走 DNS。本地开发或 Docker 环境下,这一步最容易出问题:
- 容器内运行的程序访问
mysql服务名,但宿主机或容器自己的/etc/hosts里根本没有这一行:172.18.0.3 mysql - Windows 上 PHP 连
localhost失败,是因为C:\Windows\System32\drivers\etc\hosts缺少127.0.0.1 localhost - 手误把
db.example.com写成db.example.co,/etc/hosts又没补,系统直接跳过,不报错也不 fallback,就卡住
验证方式很简单:nslookup mysql 或 getent hosts mysql;如果没返回 IP,说明 /etc/hosts 没生效或压根没配。
确认 DNS 配置是否可用且优先级合理
Linux 下 DNS 查询顺序由 /etc/nsswitch.conf 中的 hosts: 行决定,典型值是 files dns,即先查 /etc/hosts,再查 DNS。常见陷阱:
免费 DNS 与邮件安全分析(IntoDNS.ai):包括 DNSSEC、SPF、DKIM、DMARC、MTA-STS、BIMI、SMTP STARTTLS、FCrDNS、黑名单、发件人要求及报告。
-
/etc/resolv.conf被覆盖(比如 Docker 启动时没传--dns,或 systemd-resolved 未启用),导致 nameserver 是空的或指向不可达地址 - 公司内网 DNS 不支持反向解析(
dig -x 10.0.1.5超时),而 MySQL 服务端又没加skip-name-resolve,客户端连上后,服务端反过来查客户端 IP 的 hostname,直接 hang 住 - Docker Compose 默认用 bridge 网络,服务名只在 compose 网络内可解析;若你在宿主机跑客户端,
mysql这个名字根本不在宿主机 DNS 范围内
临时验证 DNS 是否工作:dig +short mysql 或 nslookup mysql 8.8.8.8(绕过本地配置直连公网 DNS)。
MySQL 服务端要不要关掉 hostname 解析?
服务端开启 DNS 解析(默认行为)会导致两个问题:一是连接慢(等反向查 client IP 的 hostname),二是权限匹配出错(比如你授权的是 'app'@'web1',但服务端把 client IP 解成 web1.internal,就不匹配)。所以:
- 除非你明确依赖 hostname 授权(比如多台应用服务器共用一个 IP,靠 hostname 区分),否则建议在
my.cnf的[mysqld]段加skip-name-resolve - 加完必须重启 MySQL,且之后所有授权语句里的
Host字段只能填 IP 或%,不能再用域名(查SELECT User, Host FROM mysql.user;确认) - 如果已有 hostname 授权,又不想改权限,可临时在
/etc/hosts里补全 client IP → hostname 映射,比调 DNS 更稳
真正容易被忽略的点是:**skip-name-resolve 只影响服务端对客户端 IP 的反向解析,不影响客户端自己解析服务端 host 名**。也就是说,你代码里写 host: 'mysql' 还是得靠客户端环境的 /etc/hosts 或 DNS 来 resolve——这个环节它管不了。

















