MySQL 在 Docker 环境下连接变慢问题记录
一、问题现象
在使用 Docker 部署 MySQL 时发现如下现象:
- 在宿主机执行:
bash
docker exec -it mysql mysql -u neuro -p
输入密码后需要 约 10 秒 才能进入 MySQL。
- 但如果先进入容器再执行:
bash
docker exec -it mysql bash
mysql -u neuro -p
则 几乎秒进。
- MySQL 连接池扩容或应用创建新连接时,也会出现明显卡顿。
二、原因分析
MySQL 默认会对客户端 IP 进行 反向 DNS 解析(Reverse DNS Lookup)。
连接建立流程如下:
客户端连接
↓
MySQL 获取客户端 IP
↓
进行 DNS 反向解析
IP → hostname
↓
根据 hostname / IP 进行权限匹配
如果 DNS 服务器无法解析该 IP 的 PTR 记录,则会等待 DNS 查询超时。
Docker 网络中的 IP(例如:172.x.x.x、10.x.x.x 等)通常 没有 PTR
反向解析记录。
因此 MySQL 每次建立连接时都会:
查询 DNS
↓
查不到记录
↓
等待 DNS 超时
↓
继续认证
DNS 超时时间通常为:
5 ~ 10 秒
因此就会出现:
输入密码 → 等待10秒 → 进入 MySQL
三、为什么容器内连接很快
当在容器内部执行:
bash
mysql -u neuro -p
连接来源通常是:
localhost
MySQL 会使用:
unix socket
而不是 TCP 网络连接,因此不会触发 DNS 解析。
连接流程变为:
本地 socket
↓
认证
↓
进入 MySQL
所以几乎 瞬间完成。
四、确认问题的方法
执行以下 SQL 查看配置:
sql
SHOW VARIABLES LIKE 'skip_name_resolve';
如果结果为:
skip_name_resolve = OFF
说明 MySQL 会进行 DNS 反向解析。
五、解决方案
在 MySQL 配置中开启:
skip-name-resolve
修改配置
编辑 MySQL 配置文件(常见路径):
/etc/mysql/mysql.conf.d/mysqld.cnf
或
/etc/my.cnf
添加:
ini
[mysqld]
skip-name-resolve
重启 MySQL
bash
docker restart mysql
六、开启后的效果
连接流程变为:
客户端连接
↓
MySQL 获取 IP
↓
直接按 IP 匹配权限
不会再执行 DNS 解析。
连接建立时间从:
≈ 10 秒
下降为:
< 1 毫秒
七、注意事项
开启 skip-name-resolve 后:
不能再使用 hostname 进行权限授权。
例如以下方式将失效:
'user'@'app-server'
必须使用:
'user'@'IP'
或
'user'@'%'
八、推荐的生产配置
Docker / Kubernetes 环境中,MySQL 推荐配置:
备注:其中skip-host-cache我没用。
ini
[mysqld]
skip-name-resolve
skip-host-cache
参数 作用
skip-name-resolve 禁用 DNS 反向解析
skip-host-cache 禁用 host 解析缓存
九、经验总结
当出现以下现象时,应优先怀疑 DNS 解析问题:
mysql -u -p登录卡住- 新建数据库连接非常慢
- Docker / Kubernetes 环境
- IP 地址为内网或容器网络
优先检查:
sql
SHOW VARIABLES LIKE 'skip_name_resolve';
如果为 OFF,建议开启 skip-name-resolve。
记录时间:2026-03-15