“lost connection to mysql server during query”本质是服务端主动或被动中断执行中查询,主因是服务端配置、资源消耗或中间链路超时;需查错误日志中“got timeout reading communication packets”,核对net_read_timeout/net_write_timeout、负载均衡空闲超时及max_allowed_packet,并结合show processlist分析线程状态与time值。

“Lost connection to MySQL server during query”不是网络断了,而是 MySQL 主动或被动中断了正在执行的查询连接——90% 以上的情况,根源在服务端配置、查询资源消耗或中间链路超时,而非客户端代码写错了。
查 MySQL 错误日志里有没有 Got timeout reading communication packets
有这行日志,基本锁定是服务端等不到客户端下一段数据。常见于:客户端卡在结果处理(比如 Python 没用 SSCursor 流式读取大结果集)、网络中间件(如 AWS NLB、阿里云 SLB)空闲超时早于 wait_timeout 触发断连、防火墙静默丢包。
- Linux 下快速定位:
sudo tail -n 100 /var/log/mysql/error.log | grep "timeout reading" - 云环境必须核对负载均衡器/NAT 网关的空闲超时值(常见 300~600 秒),它比 MySQL 的
wait_timeout更先动手 - 如果日志里同时出现
Aborted connection+read: Connection reset by peer,大概率是客户端进程已退出但 TCP FIN 没发全,服务端还在等
用 SHOW PROCESSLIST 看线程卡在哪
执行该命令后重点盯三列:State、Time、Info。如果看到 State 是 Sending data 或 Copying to tmp table 且 Time 持续上涨(比如 > 30 秒),说明查询没死,但被阻塞了。
-
Time值远大于net_read_timeout(默认 30 秒)→ 查询返回数据太慢,服务端放弃等待 -
State卡在Locked或Waiting for table metadata lock→ DDL 操作(如ALTER TABLE)阻塞了查询 -
Info显示的是一个简单SELECT,但Time超过 100 秒 → 很可能没走索引,EXPLAIN会显示rows接近千万级
确认 net_read_timeout 和 net_write_timeout 是否过小
这两个参数控制服务端读/写数据的单次等待上限,和 wait_timeout(空闲超时)完全无关。大结果集导出、长事务提交、流式读取 BLOB 都直接受它们限制。
- 查当前值:
SHOW VARIABLES LIKE 'net_%_timeout'; - 临时调高(仅本次生效):
SET GLOBAL net_read_timeout = 600; SET GLOBAL net_write_timeout = 600; - 永久生效:必须加到
my.cnf的[mysqld]段下,重启 MySQL;注意客户端驱动(如 PyMySQL、mysql-connector-python)也要同步设置对应超时(如read_timeout=600) - 别只改服务端——如果客户端驱动没设读超时,它可能在收到第一个 packet 后就自己断开了,服务端日志里反而看不到 timeout 相关记录
检查 max_allowed_packet 是否被突破
报错伴随 Error 1153: Got a packet bigger than 'max_allowed_packet' bytes 就是它。但即使没显式报这个错,大 INSERT 或含长 TEXT 字段的 SELECT 也可能在传输中途被截断,现象就是 “during query”。
- 查当前值:
SHOW VARIABLES LIKE 'max_allowed_packet';(单位是字节) - 服务端和客户端必须设成一致值,否则握手成功、查询执行一半就断
- 设为
64M是较安全的起点,但不要盲目设成1G——内存吃紧时可能触发 OOM Killer 杀掉 mysqld 进程 - PHP 的
mysqli、Python 的mysql-connector都需显式传参,例如:connect(..., connection_timeout=60, read_timeout=600, max_allowed_packet=67108864)
真正难排查的,是那些不报错、不写日志、SHOW PROCESSLIST 里也看不到残留线程的“幽灵断连”——往往藏在容器网络 MTU 不匹配、内核 tcp_fin_timeout 设置过短、或云厂商安全组动态限速策略里。这类问题必须抓包验证,不能只靠看配置。











