connection refused 或 lost connection 错误通常源于网络或客户端配置问题而非 mysql 拒绝连接;应先用 telnet/nc 测试端口连通性,再排查 ssl 强制、安全组、连接池 validationquery 配置及服务端 wait_timeout 参数。

Connection refused 或 Lost connection 错误怎么快速定位
这类报错不是 MySQL 在拒绝你,而是连接根本没发出去或中途断了。先别急着改 wait_timeout,90% 的情况是网络或客户端配置卡在半路。
常见错误现象:ERROR 2003 (HY000): Can't connect to MySQL server on 'x.x.x.x'、Lost connection to MySQL server at 'reading initial communication packet'
- 用
telnet host 3306或nc -zv host 3306直接测端口通不通,绕过所有驱动和连接池逻辑 - 如果 telnet 通但应用连不上,立刻查客户端是否启用了 SSL 强制(MySQL 8.0+ 默认 require_secure_transport=ON),而你的连接串没加
?ssl-mode=DISABLED或对应 CA 配置 - 云环境特别注意安全组/NACL 是否放行了入方向 3306,且源 IP 是实际出口 IP(不是 NAT 网关内网地址)
连接池 keep-alive 和 validationQuery 怎么配才不踩坑
连接池本身会缓存连接,但 MySQL 服务端默认 8 小时就主动断开空闲连接(wait_timeout=28800),池子却不知道——结果取出来就是“已经断掉的连接”,报 Communications link failure。
使用场景:Spring Boot + HikariCP、Druid、Tomcat JDBC Pool 等主流池都面临同样问题
- HikariCP 必须设
connection-test-query=SELECT 1(MySQL 5.7+)或connection-test-query=SELECT 1+connection-init-sql=SET NAMES utf8mb4(避免初始化失败) - 关键参数:
validation-timeout=3000(毫秒)、keepalive-time=30000(Hikari 3.2.1+ 才支持,每 30 秒发一次 SELECT 1 检活) - Druid 要开
testWhileIdle=true+timeBetweenEvictionRunsMillis=60000,否则空闲连接超时后仍被返回给业务线程
MySQL 服务端 timeout 参数哪些真影响连接存活
别一看到 “timeout” 就全调大。真正决定连接是否被服务端单方面断开的,只有两个参数:
-
wait_timeout:控制**非交互式连接**(比如应用连接池里的连接)空闲多久断开,默认 28800 秒(8 小时) -
interactive_timeout:只影响mysql命令行这种带--interactive标志的连接,对应用几乎无影响 -
connect_timeout是建立 TCP 连接阶段的超时(秒级),调太大反而掩盖网络问题;net_read_timeout/net_write_timeout影响大查询传输中断,和“连接超时”无关
改法:在 my.cnf 的 [mysqld] 下加 wait_timeout=3600(1 小时),然后 mysql> SET GLOBAL wait_timeout = 3600; 生效(重启后恢复原值)
Java 应用里 Connection.isValid() 为什么有时返回 true 却执行 SQL 失败
因为 isValid(1) 只发一个 TCP ACK 探测,不真正走 MySQL 协议握手。网络中间设备(如防火墙、云负载均衡)可能透传 ACK 但丢弃后续数据包,导致连接“看起来活着,实则废了”。
性能影响:频繁调 isValid() 会增加 RTT 延迟,尤其跨机房部署时
- 不要在每次
getConnection()后手动调isValid()—— 连接池自己的校验机制更可靠 - 若必须手动验证,至少设超时时间 ≥ 3 秒:
conn.isValid(3),避免被瞬时抖动误判 - 真正保险的做法是:捕获
SQLException中的 SQLState08S01(communication link failure)或消息含"Broken pipe"、"Connection reset",此时应废弃该连接并重试
最麻烦的地方往往不在 MySQL 本身,而在连接池没配 validationQuery、网络路径里有静默丢包的 LB、或者开发环境 hosts 写死的 IP 和生产 DNS 解析结果不一致——这些点比调 wait_timeout 更容易漏掉











