PHP 7.4 PDO遍历无缓冲查询时反复出现MySQL server has gone away错误
无缓冲PDO查询MySQL时周期性触发"MySQL server has gone away"错误
场景与实现
使用PHP 7.4脚本通过PDO操作本地MySQL 5.7的大型InnoDB表,因整张表无法载入内存,采用无缓冲查询。
查询语句为:
SELECT * FROM table WHERE field_a = ... ORDER BY field_b, field_c
该查询已优化(耗时<3秒,使用索引),EXPLAIN结果关键部分:
594802 | 5.67 | Using index condition; Using where; Using filesort
遍历结果的核心代码:
$rows = $db->prepare('redacted'); $rows->bindParam(':redacted', $redacted); $rows->execute(); foreach($rows as $r) { if($r->fieldname != redacted) doWork1(); doWork2(); }
其中doWork2()通过独立的缓冲PDO连接执行:
- 更新当前遍历的行数据
- 在事务内向另一张表插入多条数据(每行对应一条INSERT语句)
每次迭代耗时1-2秒,整个循环需数小时完成。
报错现象
脚本运行中每12分钟会抛出致命PDO异常:
[03-Feb-2023 08:34:29 Europe/Rome] PHP Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 2006 MySQL server has gone away in redacted:176 Stack trace: redacted [03-Feb-2023 08:46:50 Europe/Rome] PHP Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 2006 MySQL server has gone away in redacted:176 Stack trace: redacted
报错行固定为foreach或if语句。
同时mysqld.log记录:
2023-02-03T08:36:33.480661+01:00 781575 [Note] Aborted connection 781575 to db: 'redacted' user: 'redacted' host: 'localhost' (Got timeout writing communication packets) 2023-02-03T08:48:56.534865+01:00 781768 [Note] Aborted connection 781768 to db: 'redacted' user: 'redacted' host: 'localhost' (Got timeout writing communication packets)
日志时间戳比PHP报错晚约2分钟,推测写入超时是连接断开的结果而非原因。
已做排查
- 重启脚本后可正常处理相同数据,排除数据值/类型问题
- 调整MySQL参数:
net_read_timeout、net_write_timeout设为120秒wait_timeout设为8小时max_allowed_packet设为256MB
调整后问题依旧
- 检查所有服务器变量,未发现接近12分钟(720秒)的配置项
mysqladmin version显示服务器运行稳定,查询日志无异常
寻求解决办法
请针对该周期性连接断开问题提供可行的排查方向或解决方案。
内容的提问来源于stack exchange,提问作者Marco Marsala
相关产品推荐
相关产品推荐

