必须同时改服务端和客户端的max_allowed_packet,只动一边基本无效;因为mysql命令行工具自带默认值(通常4mb),在发包前就截断,错误error 1153多源于客户端侧限制,需分别查show variables和show session variables确认实际值,并在[mysqld]段设值、重启服务,客户端导入时显式加--max-allowed-packet参数。

必须同时改服务端和客户端的 max_allowed_packet,只动一边基本无效。
为什么改了 my.cnf 还是报 ERROR 1153
因为 mysql 命令行工具自己也有一套默认值(通常是 4MB),它在发包前就截断了——根本没机会把大 SQL 送到服务端。你看到的错误,大概率是客户端先扛不住。
- 查服务端当前值:
SHOW VARIABLES LIKE 'max_allowed_packet'; - 查客户端当前值(在
mysqlshell 里执行):SHOW SESSION VARIABLES LIKE 'max_allowed_packet'; - 图形化工具(如 Navicat、DBeaver)不读 my.cnf,得在连接参数或会话里手动设
SET SESSION max_allowed_packet = 268435456; - 宝塔用户注意:配置文件路径是
/www/server/mysql/my.cnf,[mysqld]段加max_allowed_packet = 256M,单位必须大写M,改完要service mysqld restart
命令行导入时怎么传参才生效
用 mysql 命令直接重定向导入(mysql db_name )时,<code>--max_allowed_packet 参数必须放在命令最前面,且数值单位是字节或带单位(256M),不能写成 256MB 或小写 m。
- 正确写法:
mysql --max_allowed_packet=256M -u root -p db_name - 错误写法:
mysql -u root -p --max_allowed_packet=256MB db_name (单位错 + 位置错) - 如果用
source命令在交互式 shell 里导入,得先执行:SET SESSION max_allowed_packet = 268435456; - 别忽略
net_buffer_length:它影响分包缓冲,默认 16KB,大 INSERT 多值语句容易拆包异常,建议同步设为1048576(1MB)
导入前怎么预判该设多大
不是越大越好。设太大浪费内存,还可能掩盖 SQL 文件里的脏数据(比如调试残留的超长字符串)。关键看文件里最长的一行。
- 用
awk '{print length}' dump.sql | sort -nr | head -1查最长行字节数 - 在此基础上加 20% 余量,就是安全值(例如最长行 80MB → 设 96MB)
- 纯结构 + 小数据:16M 足够;含
MEDIUMTEXT/BLOB:至少 64M;整库导出文件:优先检查最长行 - 线上环境慎设超过 256M,尤其内存紧张时;mysqldump 导出时也要加
--max-allowed-packet=256M,否则导出的 SQL 本身就会超限
实在调不动参数时的绕过方案
改参数是治标,切分或换协议更稳,特别是面对不可控的生产环境。
- 用
mysqlimport替代source:走LOAD DATA INFILE协议,不受客户端max_allowed_packet限制(但要求文件在数据库服务器本地,且secure_file_priv允许该路径) - 用
split -l 5000 dump.sql chunk_按行切分,再逐个source;注意别在事务中间切断(比如BEGIN和COMMIT之间) - 临时禁用自动提交:
SET autocommit=0;,每 1000 行左右加COMMIT;,避免单事务过大触发其他限制(如innodb_log_file_size) - 避开
INSERT INTO t VALUES (),(),()...;这种多值写法:用mysqldump --skip-extended-insert重新导出,生成单行 INSERT,包小但导入慢
最容易被忽略的是客户端和服务端的双重要求,以及 net_buffer_length 对多值 INSERT 的隐性影响——很多“已确认服务端改好了”的失败案例,其实卡在客户端或缓冲区拆包上。











