cron_schedule里大量任务处于pending,但某个group始终像被占用。服务器上又看不到对应PHP进程。除了查长任务,还要检查该组的use_separate_process与进程锁是否在异常退出后未释放。

排查记录

我保留了一个失败样本,并用同样输入在无缓存或单节点条件下再跑一遍。这样可以把前端假象、缓存和真正的数据问题分开。

我先看了这几处

  • 先按job_code统计pending/running/error,确认是单任务堵塞还是整组不调度。
  • 核对系统cron是否同时以不同用户启动,文件锁目录权限不同会造成各跑各的。
ps -ef | grep "cron:run" | grep -v grep
mysql -e "SELECT job_code,status,COUNT(*) c,MIN(scheduled_at) oldest FROM cron_schedule GROUP BY job_code,status ORDER BY oldest;"
bin/magento cron:run --group=index -vvv
grep -R "use_separate_process" app/code vendor/*/etc/crontab.xml app/etc/env.php

日志取样要带上请求时间、Store View、实体ID和部署版本。只截一行异常往往不够,至少保留错误前后几十行,才能判断是入口参数还是后续状态被改写。

处理办法

先停止重复的系统cron入口,只保留同一部署用户。确认没有活进程后,把超出合理时长的running记录标记为error并写明manual recovery;清理var/locks或配置的lock provider中的孤儿锁。若单任务经常超过周期,拆分批次或调整schedule_lifetime,不要简单把所有组都改为separate process。

修改范围

  • 先在单个SKU、单个订单或单个Store验证。
  • 保留可回退的旧配置,不覆盖原始证据。
  • 需要批量处理时分批提交并输出成功/失败清单。

回归时别只刷新页面

  • cron:run返回后锁能释放
  • 新schedule按分钟生成并从pending进入success
  • 同一job_code没有并发两份
  • 24小时内running数量稳定

验收不只看后台提示“成功”。我还会从前台/API再走一次真实链路,并在下一轮cron、索引或缓存命中后重复检查,确认不是短暂正常。

补记

不要一刀切清空cron_schedule,先保留故障时间窗用于定位。