根本原因是dns反向解析:mysql默认对客户端ip执行gethostbyaddr()查hostname,网络不佳时延迟数百毫秒甚至超时;高并发下大量connecting状态积压。

为什么 MySQL 建立连接慢,尤其在高并发时?
根本原因常是 DNS 反向解析:客户端 IP 进来后,MySQL 默认会尝试做 gethostbyaddr() 查 hostname,这个过程在网络不稳定或 DNS 服务响应慢时可能卡住几百毫秒甚至超时。高并发下大量连接同时触发,积压严重,SHOW PROCESSLIST 里能看到一堆 Connecting 状态。
skip-name-resolve 能不能直接关掉 DNS 解析?
能,但只作用于服务端——它禁止 MySQL 用客户端 IP 去查 hostname,所有授权必须基于 IP(如 'user'@'192.168.1.%'),不能再用 'user'@'app-server' 这类主机名形式。
实操建议:
- 确认所有
mysql.user表里的Host列值都是 IP 或 IP 段,不含域名;否则授权会失效 - 修改配置文件
/etc/my.cnf或/etc/mysql/mysql.conf.d/mysqld.cnf,在[mysqld]下加一行:skip-name-resolve - 重启 MySQL 生效(注意:不是 reload,必须 restart)
- 验证是否生效:执行
SELECT @@skip_name_resolve;,返回ON即成功
开了 skip-name-resolve 还连不上?检查这几个点
常见错误现象:开完之后部分应用报 Access denied for user,或连接被拒绝。
原因和对策:
- 应用连接串里写的是域名(如
host=app-db.example.com),而 MySQL 授权用的是 IP —— 这没问题,DNS 解析由客户端完成,MySQL 不参与;但你要确保客户端解析出的 IP 确实在授权范围内 - 本地开发环境用
127.0.0.1连,但授权只给了'user'@'localhost'—— 注意:localhost在 MySQL 里走 socket,不走 TCP,且skip-name-resolve对它无影响;若要用 TCP 连本地,显式写127.0.0.1,并确保有对应授权 - Docker 或 Kubernetes 场景下,容器内 /etc/hosts 没配、或网络插件导致 IP 动态变化,授权 IP 段太窄 —— 建议用 CIDR 授权,比如
'app'@'10.42.0.0/16'
还有没有比 skip-name-resolve 更治本的办法?
有,但要配合架构调整:连接池复用连接,而不是每次请求都新建。MySQL 本身不擅长高频建连,skip-name-resolve 只是减负,不是扩容。
关键点:
- 应用层必须启用连接池(如 Java 的 HikariCP、Python 的 SQLAlchemy + pool_pre_ping),并合理设置
max_pool_size和idle_timeout - 避免 ORM 自动“ping before use”却没配
pool_recycle,导致大量半死连接堆积 - MySQL 侧调大
max_connections前先看Threads_connected和Aborted_connects,后者持续上涨说明连接建立阶段就在失败,优先排查网络或 skip-name-resolve 配置
真正麻烦的从来不是要不要加 skip-name-resolve,而是改完之后忘了同步更新权限表,或者误以为它能替代连接池。这两处一漏,问题照旧。











