执行大SQL断连通常因max_allowed_packet过小,服务端限制单包大小(默认4MB),需修改配置文件中[mysqld]段的max_allowed_packet=64M并重启,同时客户端工具如mysqldump也要同步设置对应参数。

为什么执行大SQL时突然断连
MySQL客户端报错 Lost connection to MySQL server during query,十有八九不是网络问题,而是服务端在解析或返回结果时被“卡住”了——max_allowed_packet 太小,导致单条语句或结果集超限后直接中断连接。
这个值控制的是服务器能接收/发送的**单个数据包最大字节长度**,不是总传输量。插入一条含 20MB JSON 字段的记录、导出一个大视图、或者用 mysqldump 备份带长文本的表,都容易触发它。
- 默认值通常只有 4MB(MySQL 5.7+),老版本甚至 1MB
- 客户端和服务器端各自有该参数,但起作用的是**服务端的设置**;客户端设得再大,服务端拦不住照样断
-
SET SESSION max_allowed_packet = ...只影响当前连接,重启或新连接就失效
怎么查当前生效值
别猜,直接连上 MySQL 查:
SELECT @@global.max_allowed_packet, @@session.max_allowed_packet;
注意看 @@global 值——这才是持久生效的底线。如果它还是 4194304(即 4MB),而你正处理 8MB 的 blob,那断连就是必然的。
- 单位是字节,不是 KB/MB,输出数字看着吓人,其实是 4 * 1024 * 1024 = 4194304
- 如果只改了 session 级,
@@session会变,但@@global不动,新连接仍走老值 - 某些托管数据库(如阿里云 RDS、AWS RDS)不开放 global 修改权限,得去控制台配参数组
永久修改 max_allowed_packet 的正确姿势
临时 SET 只能救急,真正要稳,得改配置文件并重启服务(或用参数组):
- 编辑 MySQL 配置文件(通常是
/etc/my.cnf或/etc/mysql/mysql.conf.d/mysqld.cnf) - 在
[mysqld]段落下加一行:max_allowed_packet = 64M(支持M/G后缀) - 重启 MySQL:
sudo systemctl restart mysql(或mysqld) - 确认生效:
SELECT @@global.max_allowed_packet;应返回 67108864
别写成 max_allowed_packet = 64*1024*1024,MySQL 不认表达式;也别设得过大(比如 2G),可能引发内存分配失败或 OOM Killer 干掉 mysqld 进程。
客户端也要同步调大(尤其 mysqldump 和 LOAD DATA)
服务端放宽了,客户端工具自己也有包大小限制。比如 mysqldump 默认只认 24MB,哪怕服务端设了 64M,dump 大表时仍可能报错。
- 导出时加参数:
mysqldump --max-allowed-packet=64M -u root ... - 导入时同样要加:
mysql --max-allowed-packet=64M -u root ... - 程序里(如 Python 的 PyMySQL)需显式传参:
max_allowed_packet=67108864到connect() - Java 的 JDBC URL 可加:
&maxAllowedPacket=67108864
这个客户端参数只是告诉驱动“你可以发多大的包”,它不会影响服务端判断——两边都得对齐,否则就在半路被截断。
最容易被忽略的是:改完服务端配置没重启,或者只改了 my.cnf 里的 client 段(对服务端无效),又或者用 Docker 启动 MySQL 却忘了把新配置挂载进去。断连看起来像随机故障,其实每一步都有迹可循。


















