迁移失败大概率是目标库max_allowed_packet比源库小或未同步调大,确认方法:错误日志含“packets larger than max_allowed_packet are not allowed”或“packet for query is too large (x > y)”,登录目标库执行select @@global.max_allowed_packet;配置须严格写在[mysqld]段、单位用m、重启服务生效,客户端如mysql命令行也需同步加--max-allowed-packet参数。

迁移失败大概率是目标库 max_allowed_packet 比源库小,或根本没同步调大——不是“可能”,而是几乎每次都这样。
怎么一眼确认就是它卡住的
别靠猜,直接看错误日志和当前值:
- 错误信息里出现
Packets larger than max_allowed_packet are not allowed或Packet for query is too large (8808741 > 4194304),括号左边是实际包大小(字节),右边是当前限制,基本坐实 - 登录目标库执行:
SELECT @@global.max_allowed_packet;——注意必须用@@global,SHOW VARIABLES LIKE 'max_allowed_packet'默认查的是 session 级,常被 ORM 或连接池覆盖,不准 - 云数据库(如阿里云 RDS)通常禁用
SET GLOBAL,查出来仍是默认值,得去控制台改参数组,不能只信命令行输出
为什么改了配置文件还是失败
改了 /etc/my.cnf 却没生效,常见原因就三个:
- 配置写错段落:必须严格放在
[mysqld]下,写在[client]、[mysql]或无段落处,MySQL 启动时完全忽略 - 单位写错:允许写
max_allowed_packet = 512M,但写成512MB、512m或带空格的512 M,会导致mysqld启动失败 - 没真正重启服务:
mysqladmin reload或SIGHUP不重载此参数,必须执行systemctl restart mysql(或对应服务名)
客户端和应用层也得同步设
服务端调大只是第一步,客户端工具和代码连接池不跟上,照样在本地截断:
-
mysql命令行导入大 SQL:必须显式加参数,mysql --max-allowed-packet=512M -u root -p db_name ;在交互式中用 <code>source,得先执行SET SESSION max_allowed_packet = 536870912; - JDBC 连接串要加
maxAllowedPacket=536870912;PDO 要设PDO::MYSQL_ATTR_MAX_BUFFER_SIZE;Django 的OPTIONS里也得填 -
mysqldump导出时同样要加--max-allowed-packet=512M,且参数必须放在数据库名之前,单位必须大写M
主从、云环境和边界情况最容易漏
这些地方一漏就白调:
- 主从同步失败报
Last_IO_Error: log event entry exceeded max_allowed_packet?说明从库解析不了主库 binlog event —— 主库和从库的max_allowed_packet必须一致,且都得在[mysqld]段配置并重启 - 云数据库(RDS、TencentDB)不开放
SET GLOBAL,必须走控制台修改参数模板,改完还得重启节点才生效 - 设成 1G 还报错?真凶可能是单行数据里混入未转义换行符,导致 MySQL 把整行当一个 packet 解析——这时该检查源文件行宽,而不是继续调大参数
最常被跳过的动作:改完配置后,没分别登录主库、从库、应用连接池后台,执行 SELECT @@global.max_allowed_packet; 验证数值是否真的对齐。三端不一致,迁移就永远卡在“写入一半就断”。











