max_allowed_packet 限制单个网络包最大尺寸,影响查询语句、结果集、blob等传输;超限直接报错中断连接,需服务端与客户端同步配置,推荐起步值50–100mb。

max_allowed_packet 设得太小会直接导致大查询失败或结果截断,不是“性能差”,而是“根本传不过去”。
为什么 max_allowed_packet 会影响网络传输?
这个参数限制的是单个网络包(packet)的最大尺寸,不是缓冲区或带宽。MySQL 客户端与服务端之间所有数据——包括查询语句本身、返回的结果集、LOAD DATA 导入内容、甚至 INSERT ... VALUES (...) 的批量值——都必须装进一个 packet 里传输。一旦超限,服务端直接报错 Packet for query is too large 或 Got a packet bigger than 'max_allowed_packet' bytes,连接可能中断。
它不控制吞吐量,但卡在“能不能传”的第一道门槛上。尤其在导出大 JSON 字段、批量插入千行以上、或 SELECT 返回含 MEDIUMTEXT 的记录时,极易触发。
怎么设才合理?
不能拍脑袋填 1G,也不能死守默认的 4MB。关键看业务中最常出现的“最大单次传输单元”:
- 查当前值:
SHOW VARIABLES LIKE 'max_allowed_packet'; - 临时调高(重启前生效):
SET GLOBAL max_allowed_packet = 67108864;(即 64MB) - 永久生效:在
my.cnf的[mysqld]和[client]段分别加一行:max_allowed_packet = 64M - 客户端和服务端必须一致:如果只改服务端,而 JDBC 连接串没配
maxAllowedPacket,或 MySQL 命令行没加--max-allowed-packet=64M,照样失败 - 注意单位:MySQL 配置中支持
K/M/G后缀,但某些旧版客户端(如部分 Python MySQLdb)只认字节数,需换算
容易被忽略的坑
这个参数不是越大越好,有三个隐性代价:
- 内存占用翻倍:每个连接都会为该 packet 分配两份缓冲(收 + 发),设成 1G 意味着每个空闲连接至少吃掉 2GB 虚拟内存,
max_connections高时极易 OOM - 影响复制稳定性:主从之间 binlog event 也受此限制。若主库设了 64M,从库却只设 4M,IO 线程直接报错退出
- 和
net_buffer_length协同工作:后者是初始分配缓冲大小,默认 1MB;当实际数据超过它,MySQL 才会按需扩容到max_allowed_packet上限。所以net_buffer_length太小会导致频繁 realloc,反而降低小包效率
真正卡住网络传输的,往往不是带宽或延迟,而是这个看似不起眼的“包上限”。它不报慢,只报错;不拖性能,只拦路。上线前务必用真实最大查询压测一遍,而不是依赖文档推荐值。











