MySQL 报错Got a packet bigger than max allowed packet 调整配置|Duuu笔记
max_allowed_packet 是 MySQL 服务端和客户端能接收的最大单个数据包大小,影响 SQL 语句、结果集、BLOB、LOAD DATA 等传输;需同时配置服务端(my.cnf 中 [mysqld] 段或 SET GLOBAL)和客户端(命令行/JDBC/驱动参数),单位注意区分(配置文件支持 M,SQL 必须字节整数);推荐起步值 50–100MB,避免盲目设过大引发 OOM 或复制延迟。
max_allowed_packet 是什么,为什么改它
这个配置项控制 MySQL 服务端和客户端能接收的最大单个数据包大小。不是“上传文件大小”,而是 SQL 语句、结果集、BLOB 字段、LOAD DATA 的行数据等在传输过程中打包的上限。超过就直接报错
Got a packet bigger than max_allowed_packet
,连接中断,不给重试机会。
常见触发场景:
INSERT
含超长 JSON 字符串、
UPDATE
批量写入大文本、用
mysqldump
恢复含大 BLOB 的库、ORM 执行带巨量参数的批量插入(比如 1000 行 × 每行 2MB)。
怎么改:服务端 vs 客户端要分开设
MySQL 的
max_allowed_packet
有两套独立值:服务端(
mysqld
进程)和客户端(
mysql
命令行、JDBC、Python 的
pymysql
等)。只改服务端,客户端仍可能因自身限制提前截断;只改客户端,服务端照样拒绝大包。
Action Figure AI
借助Action Figure AI的先进技术,瞬间将照片转化为定制动作人偶。
下载
服务端生效需重启或动态设置:
SET GLOBAL max_allowed_packet = 64*1024*1024;
(64MB),但该值在重启后丢失;持久化必须写进配置文件
/etc/my.cnf
或
/etc/mysql/mysql.conf.d/mysqld.cnf
的
[mysqld]
段下:
max_allowed_packet = 64M
客户端也要配:命令行启动加
--max-allowed-packet=64M
;JDBC URL 加
&maxAllowedPacket=67108864
;Python 的
pymysql.connect()
传参
max_allowed_packet=67108864
注意单位:配置文件里支持
64M
,但 SQL 语句里必须是整数字节(如
67108864
),不能写
64*1024*1024
改多大才安全?别盲目拉到 1G
设太大不光浪费内存,还会放大问题:超大包失败时重传成本高、OOM 风险上升、主从复制延迟加剧(尤其 binlog 格式为
STATEMENT
时,一个大包可能对应几万行变更)。
先确认真实需求:用
SELECT LENGTH(blob_col) FROM tbl ORDER BY LENGTH(blob_col) DESC LIMIT 1;
查当前最大单字段长度;用
SHOW VARIABLES LIKE 'max_allowed_packet';
看当前值
推荐起步值:50–100MB。够覆盖绝大多数业务大字段场景,又不至于失控
若用
mysqldump
,记得加
--max-allowed-packet=128M
参数,它的默认值不读全局配置
云数据库(如阿里云 RDS、AWS RDS)通常限制修改该参数,得走控制台申请或选更高规格实例
改完没生效?检查这三处
最常踩的坑不是不会设,而是设了却没起作用——因为生效层级或加载顺序错了。
配置文件路径是否正确?
mysqld --help --verbose | grep "Default options"
能看到实际加载的 cnf 文件列表,优先级从高到低:命令行 >
/etc/my.cnf
>
/etc/mysql/my.cnf
>
$MYSQL_HOME/my.cnf
>
~/.my.cnf
确认改的是
[mysqld]
段,不是
[client]
或
[mysql]
段(后者只影响客户端工具,不影响服务端接收能力)
动态 SET 后没验证:执行
SHOW VARIABLES LIKE 'max_allowed_packet';
,对比
GLOBAL
和
SESSION
值;新连接才继承 GLOBAL,旧连接保持原 SESSION 值
服务端配置改完必须重启或
SET GLOBAL
,但客户端连接不重启就不会读新值;很多问题卡在这一步,而不是配置本身写错了。
