直接查failed_jobs表的exception字段可定位90%失败原因;需先运行php artisan queue:failed-table和migrate建表,注意laravel 9+主键为char(36);用sql或导出csv查看完整exception,通过json_extract解析payload获取任务类与参数;重试应优先使用queue:retry命令。

直接查 failed_jobs 表的 exception 字段,90% 的失败原因就在这里——不是猜配置、不是重启服务,先看错在哪。
确认 failed_jobs 表是否已创建
这个表不会自动出现,必须手动建:
- 运行
php artisan queue:failed-table生成迁移文件 - 再执行
php artisan migrate - 如果表还是没出来,进 phpMyAdmin 查
migrations表:SELECT * FROM migrations WHERE migration LIKE '%failed_jobs%';—— 没结果就说明迁移根本没跑成功 - Laravel 9+ 默认主键是
char(36)(UUID),旧版本是bigincrements,字段类型不匹配会导致重试失败
快速定位异常内容
phpMyAdmin 浏览视图默认只显示 exception 前 50 字符,真实堆栈往往藏在后面:
- 点对应行右侧「编辑」按钮,展开完整内容
- 或直接执行 SQL:
SELECT id, exception FROM failed_jobs WHERE id = 123; - 复制
exception值到本地 IDE 或 JSON 格式化工具解析(注意换行和单引号可能被截断) - 更稳妥方式:用 phpMyAdmin 「导出」→「自定义」→ 取消勾选「截断长文本」,导出为 CSV 再查看
从 payload 反推任务类与参数
payload 是 JSON 字符串,里面存着真正要执行的任务类、方法和参数:
- 执行这条 SQL 快速提取:
SELECT id, JSON_UNQUOTE(JSON_EXTRACT(payload, '$.job')) AS job_class, JSON_EXTRACT(payload, '$.data.command') AS command FROM failed_jobs WHERE id = 123; - 如果返回空,可能是 Laravel 8 之前的老格式(PHP
serialize()),此时需用php artisan tinker加载该记录再unserialize() - Laravel 9+ 默认用 JSON 驱动,但如果
config/queue.php里 database 连接没配对序列化方式,也可能混用格式
重试前检查关键字段状态
别直接在 phpMyAdmin 里手动改 attempts 或清空 reserved_at:
- Laravel 重试逻辑依赖
attempts、available_at和reserved_at的组合判断 - 优先用 Artisan 命令重试:
php artisan queue:retry 123或php artisan queue:retry all - 若报
unserialize(): Error at offset,大概率是payload被 MySQL TEXT 截断了(最大 65535 字节),可临时执行:ALTER TABLE failed_jobs MODIFY payload MEDIUMTEXT;











