“Lost connection to MySQL server during query”通常表示查询执行中途断连,需重点排查查询超时和网络中断:先查MySQL错误日志是否有“Got timeout reading communication packets”,再用SHOW PROCESSLIST观察线程状态(如Sending data卡住)及Time值;云环境还需检查负载均衡器/NAT网关空闲超时设置(常为300~600秒),其可能早于wait_timeout触发断连。

“Lost connection to MySQL server during query” 怎么定位
这个错误通常不是连接没建起来,而是查询中途断了。重点查两件事:查询是否真超时、网络链路是否在中间被掐断。
- 先看 MySQL 错误日志里有没有
Got timeout reading communication packets—— 有就说明服务端等不到客户端发来的下一段数据,大概率是网络卡顿或防火墙主动 kill 了长连接 - 用
SHOW PROCESSLIST查对应线程状态:如果看到State是Sending data或Copying to tmp table卡住很久,再结合Time列(秒数),基本能判断是不是慢查询触发了max_execution_time或服务端强制中断 - 如果是云环境,检查负载均衡器/NAT网关的空闲超时设置(常见 300~600 秒),它比 MySQL 的
wait_timeout更早动手
“Lost connection at handshake” 必须立刻查的 3 个点
握手阶段就断,说明连接根本没进 MySQL 的逻辑层。别急着改配置,先确认底层通不通。
-
telnet mysql-server-ip 3306如果秒断,不是 MySQL 没启,就是防火墙/安全组没放行 3306 —— 尤其注意云厂商控制台里的“入方向规则”是否漏配 - 执行
netstat -tulnp | grep :3306,输出为空?说明 MySQL 没监听任何地址,去翻my.cnf里的bind-address:设成127.0.0.1就只能本地连,要外网必须是0.0.0.0或具体外网 IP - 如果
telnet能通但握手还是断,抓包看前三次 TCP 握手后有没有收到 MySQL 的初始包(tcpdump -i any port 3306 -c 20),没有就说明 MySQL 进程压根没响应,可能是 OOM 被 kill 或磁盘满导致启动失败
wait_timeout 和 interactive_timeout 差在哪
这两个参数名字像,但影响完全不同的连接类型。混淆它们会导致改了也白改。
-
wait_timeout只管非交互式连接,比如 Java 应用用 JDBC 建的连接、PHP 的 mysqli_connect —— 这才是你应用里绝大多数连接的“寿命控制器” -
interactive_timeout只影响 MySQL 命令行客户端(mysql -u root -p)这类交互式会话,改它对 Web 应用没用 - 两者默认都是 28800 秒(8 小时),但如果你的应用连接池设置了
idleTimeout=300000(5 分钟),那实际连接生命周期由连接池控制,MySQL 的 timeout 就成了兜底项,不建议盲目调大
autoReconnect=true 看似省事实则埋雷
加这个参数能让 JDBC 在断连后自动重试,但官方文档明确说“不推荐”,因为副作用太实在。
- 事务会直接回滚,
INSERT或UPDATE执行一半断了,重连后不会继续,也不会报错,数据就丢了 - 原来连接上建的临时表、用户变量(如
@counter := @counter + 1)、预编译语句全失效,新连接是干净的,但业务代码可能还依赖旧上下文 - 更麻烦的是,某些老驱动(比如 MySQL Connector/J 5.x)开启后,遇到网络抖动会反复重连+重试,把
max_connections快速打满,引发连锁雪崩
connection-test-query=SELECT 1 配合 validation-timeout,或者 Druid 的 testWhileIdle。断连这事,得在连接被取出来用之前就发现,而不是用的时候才硬扛。



















