必须服务端、客户端、PHP层、资源限制四端协同调大max_allowed_packet:服务端my.ini中[mysqld]和[client]节均设为64M;PHP层用mysqli->options()或php.ini设mysqli.max_allowed_packet;并同步放宽PHP内存、超时及Nginx的client_max_body_size与fastcgi_read_timeout。

要让 MySQL 在高并发场景下稳定处理大字段 BLOB 写入,不能只调大 max_allowed_packet,必须服务端、客户端、PHP 层、资源限制四端协同。单独改一个地方,容易出现“改了没用”或“突然断连”的情况。
服务端配置必须双节同步修改
在 phpEnv 的 my.ini(路径如 D:\phpEnv\phpenv\mysql\my.ini)中,必须同时修改 [mysqld] 和 [client] 两个节,否则高并发下部分连接仍走默认值:
-
[mysqld]下添加:max_allowed_packet = 64M(建议起步值,够存 20MB 左右图片或 PDF) -
[client]下添加:max_allowed_packet = 64M(确保命令行、mysqldump、PHP 建立的新连接都继承该值) - 不推荐设为 1G 或更高——MySQL 内部缓冲区按此值预分配,过高易触发 OOM Killer 杀进程
重启服务并验证真实生效值
仅改配置文件不重启,等于没改。在 phpEnv 控制面板中单独重启 MySQL 服务(不是 Apache/Nginx),然后执行:
SELECT @@global.max_allowed_packet, @@session.max_allowed_packet;
返回两个数值都应为 67108864(即 64×1024×1024)。若 @@global 没变,说明 my.ini 路径错或未被加载;若 @@session 明显偏小,说明 PHP 连接时带了低值参数或 ORM 主动覆盖。
PHP 层需主动适配连接上下文
即使 MySQL 服务端已调大,PHP 的 mysqli/PDO 驱动仍可能沿用旧协商结果,尤其在长连接复用或连接池场景下:
- 对 mysqli:连接成功后立即执行
$mysqli->options(MYSQLI_OPT_MAX_ALLOWED_PACKET, 67108864); - 对 PDO:无法运行时动态设置,稳妥做法是在
php.ini中加一行mysqli.max_allowed_packet = 64M(注意这是 PHP 扩展级限制,非 MySQL 服务端) - 避免使用
mysql_connect()(已废弃),它根本不支持该选项
高并发下的内存与超时兜底措施
写入大 BLOB 不只是网络包问题,更是资源调度问题。并发多路写入 50MB 文件时,PHP 内存和脚本超时会先于 MySQL 报错:
- 插入前检查并临时放宽内存限制:
ini_set('memory_limit', '256M'); - 延长执行时间:
set_time_limit(300);(5 分钟,避免超时中断) - 不建议用
file_get_contents()一次性读全大文件——改用流式处理或分片插入,降低单次内存峰值 - Web 服务器(如 Nginx)也要同步调大
client_max_body_size和fastcgi_read_timeout,否则请求在到达 PHP 前就被拦截


















