DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

MySQL 导入报 ERROR 1153:客户端与服务端的包大小都要检查

导入大 BLOB 或多行 INSERT 时,仅改 mysql 客户端上限可能无效。检查服务端、连接继承值和备份语句,再评估临时调整与恢复重试。

使用 mysql < dump.sql 导入备份时,如果出现 ERROR 1153 和 Got a packet bigger than 'max_allowed_packet' bytes,只给导入命令加 --max_allowed_packet 可能仍然失败。客户端与服务端各自限制包大小,两边都要容得下出错的那条 SQL。

这里讨论 MySQL 8.0/8.4 的 SQL 文件导入。大 BLOB、多行 INSERT 都可能触发限额;数据库备份文件总大小不能直接用来决定参数值。数百 MB 的文件可以包含很多小语句,也可能包含一条很大的语句。

先确认导入落在哪台服务器

使用与导入任务相同的主机、端口和账号连接,执行只读查询:

SELECT @@hostname, @@port, VERSION();
SHOW GLOBAL VARIABLES LIKE 'max_allowed_packet';
SHOW SESSION VARIABLES LIKE 'max_allowed_packet';

GLOBAL 显示服务器全局值,SESSION 显示当前连接继承的值。调整全局参数后,已有连接的会话值可能仍是旧值,需要重新连接核对。MySQL 的该会话变量是只读的,不应尝试用 SET SESSION max_allowed_packet 修改。

SQL 查询到的是服务端变量,不能替代 mysql 客户端参数检查。图形客户端、导入程序与命令行客户端也可能有不同限制。

如果参数已改但查询仍显示旧值,先查是否连接了另一套实例、是否编辑了未被加载的配置,或是否仍在使用旧连接。不要继续叠加参数掩盖目标实例不一致的问题。

一次导入可临时调整全局值

先记录原值,再由有权限的管理员调整。以下是将服务端上限临时设为 128 MiB 的示例值,不代表所有备份都需要这个大小:

SET GLOBAL max_allowed_packet = 134217728;
SHOW GLOBAL VARIABLES LIKE 'max_allowed_packet';

MySQL 8.0/8.4 通常要求 SYSTEM_VARIABLES_ADMIN,或兼容场景中的 SUPER 权限;托管服务可能要求通过参数管理界面修改。不要将管理权限授予导入应用来绕过权限错误。

然后开启一个新的导入连接,并显式设置客户端上限。下面所有名称都是示例:

mysql --host=db.example.net --port=3306 --user=import_user --password \
  --max_allowed_packet=128M app_restore < dump.sql

--password 让客户端交互询问密码。app_restore 应是准备好的恢复目标,不能因示例名称相近而误导入生产库。远程连接还需保留环境已经要求的 TLS 配置。

调大限额允许更大的请求占用内存,实际内存按需分配,多个并发大请求仍会增加压力。按最大语句或行的实际需求留余量,不应直接设到 1 GiB 上限,也不必同时无依据地增大 net_buffer_length。

SET GLOBAL 不会让这个设置自动跨重启保留。一次性恢复结束后,由管理员将全局值改回事先记录的数值,并注意旧连接的会话值可能继续保持调整时的值。

长期需要时再修改持久配置

如果应用正常业务就需要较大的包,可在实际加载的服务端配置中设置,例如:

[mysqld]
max_allowed_packet=128M

服务端选项应放在服务端组,客户端设置则属于对应客户端参数或选项组。修改前保存原配置,确认部署是否通过容器启动参数、挂载文件或托管参数管理;不要假定所有机器都使用同一个 my.cnf 路径。

通过配置文件生效通常需要安排重启。重启会中断连接,先确认备份、维护窗口和依赖服务重连能力。启动失败时恢复原文件和原启动参数,再按既有部署方式启动;随后查询实际运行值确认,而不是只检查文件已经改过。

仍失败时,看单条语句是否异常

先检查报错行附近的完整 SQL,特别是多行 INSERT 与超大 BLOB。包上限约束单条 SQL 等通信单位,不是整个文件;按文件行数机械切割,可能截断字符串、转义或事务边界。

若主要问题是多行 INSERT 聚合过大,而且可以重新取得一致性备份,可保留原备份策略,只在导出参数中加入 --skip-extended-insert,让各行使用独立插入语句。这样通常增加文件大小和恢复耗时,也不能缩小单行本身的 BLOB。不要用它替换备份的一致性、权限或存储引擎方案。

如果一条语句或单行仍超过协议限制,继续调大参数无法解决,应选择适合该数据大小的迁移方式,或调整业务存储设计。SQL 由程序拼接或被手工编辑过时,还要检查引号、语句结束位置等完整性,不把所有断连都归因于包大小。

重试前处理已完成的部分

普通 SQL 导入并不保证整份文件原子提交。报错前的建表、插入或其他语句可能已经生效,直接重跑可能产生重复数据,也可能执行备份中自带的删表语句。

保留失败日志和原文件,先确认恢复目标中的实际状态。对可以重建的专用恢复库,按既有恢复流程回到明确起点;对已有业务数据的库,先备份并评估已提交内容,不直接删库重来,也不要用 --force 把失败隐藏成部分完成。

成功标准是新连接中的限额符合预期、完整导入结束无包大小错误,并完成表、行数与关键数据核对。导入进程退出成功只能说明命令执行完毕,不能代替恢复结果验收。