Laravel队列任务导入大CSV失败,未进入失败任务表
问题描述
用LOAD DATA INFILE导入100M的大型CSV到MySQL表时,执行5-20分钟会随机失败,失败后任务仍留在jobs表,没转到failed_jobs表。worker日志报错不固定,包括:
- PDOException(错误码2002:无此文件或目录、连接被拒绝)
- SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
注:MySQL客户端已配置失败重连,且相同代码、数据在MariaDB环境下完全正常。
相关配置
Supervisor配置
[program:laravel-worker] process_name=%(program_name)s_%(process_num)02d command=php /var/www/web/tinytest/artisan queue:work --sleep=30 autostart=true autorestart=true stopasgroup=true killasgroup=true user=www-data numprocs=1 redirect_stderr=true stdout_logfile=/var/www/web/tinytest/storage/logs/worker.log stopwaitsecs=3600
MySQL配置(my.cnf)
[mysqld] innodb_file_per_table=ON innodb_flush_method=O_DIRECT innodb_log_file_size=1G innodb_buffer_pool_size=3G max_allowed_packet = 256M
排查与解决办法
调大MySQL连接超时参数
在my.cnf的[mysqld]段添加以下配置:wait_timeout = 86400 interactive_timeout = 86400大文件导入耗时久,默认超时时间会让MySQL主动断开连接,调大后避免这种情况。修改后重启MySQL服务生效。
优化Laravel队列Worker的连接与超时设置
- 修改Worker启动命令,增加
--timeout参数,设置足够覆盖导入耗时的超时值(比如3600秒):
防止Worker进程被Laravel或Supervisor超时终止,引发连接异常。php /var/www/web/tinytest/artisan queue:work --sleep=30 --timeout=3600 - 打开
config/database.php,在MySQL配置项里添加PDO参数,强制断开后自动重连:'options' => [ PDO::ATTR_PERSISTENT => false, PDO::ATTR_AUTOCOMMIT => true, PDO::ATTR_TIMEOUT => 3600, ],
- 修改Worker启动命令,增加
优化
LOAD DATA INFILE执行效率- 导入前临时关闭目标表索引,减少索引维护开销:
导入完成后重新开启索引:ALTER TABLE your_target_table DISABLE KEYS;ALTER TABLE your_target_table ENABLE KEYS; - 如果权限允许,改用
LOAD DATA LOCAL INFILE导入,用客户端文件而非服务器端文件,规避潜在的权限或IO问题。
- 导入前临时关闭目标表索引,减少索引维护开销:
检查MySQL服务器资源状态
- 导入时监控MySQL的CPU、内存、磁盘IO使用率,确认是否因资源耗尽导致连接中断。
- 查看MySQL错误日志(通常在
/var/log/mysql/error.log),排查是否存在OOM、进程崩溃等服务器层面的问题。
确认Supervisor超时设置
当前stopwaitsecs设为3600秒(1小时),如果导入耗时可能超过这个时间,需要进一步调大该参数,避免Supervisor提前终止Worker进程。
内容的提问来源于stack exchange,提问作者discodancer
相关产品推荐
相关产品推荐

