Magento 2 索引设置为 Update by Schedule 后,后台或 CLI 长期显示 suspended,商品修改不再自动反映到前台。直接执行一次全量 reindex 可能让页面暂时更新,但 suspended 的调度状态没有恢复,下一次增量更新仍会停止。

先记录每个索引器的模式和状态

bin/magento indexer:show-mode
bin/magento indexer:status
bin/magento indexer:info

确认是一个 indexer suspended,还是依赖链上的多个索引一起停止。价格、库存、分类和搜索索引可能存在依赖,上游失败会影响下游。不要一上来 reset 全部索引器,否则会丢失定位证据并制造昂贵的全量重建。

查看 MView 状态和版本进度

SELECT view_id, mode, status, version_id, updated
FROM mview_state
ORDER BY view_id;

再查看对应 changelog 表的最大 version_id,与 mview_state 记录比较。差距持续扩大说明变更在积压;状态显示 working 但没有活跃进程,可能是上次进程异常退出留下状态;suspended 则要追查是谁挂起以及此前的错误。

确认 index Cron 组持续运行

定时索引依赖 Cron 消费 changelog。检查 cron_schedule 中 index 相关任务的 pending、running、missed 和 error,结合 messages 与日志判断。系统 crontab 正常不代表 index 组一定成功,长任务、锁或 PHP 内存仍可能让它退出。

SELECT job_code, status, scheduled_at, executed_at,
       finished_at, messages
FROM cron_schedule
WHERE job_code LIKE 'index%'
ORDER BY schedule_id DESC
LIMIT 50;

部署挂起与故障挂起处理不同

某些部署流程会主动 suspend scheduled indexer,避免代码切换时写入不一致。若部署脚本异常中断,恢复步骤没有执行,索引就一直挂起。检查部署记录和自动化脚本,保证失败分支也能明确恢复或告警。

如果是数据错误导致消费者失败,先单独运行相关索引并保留第一条异常。常见根因包括孤立实体、重复键、搜索服务不可用、内存不足和数据库锁。修复根因后,再按当前 Magento 版本支持的命令恢复状态并重建相关索引。

reset 不是修复,只是重置状态

indexer:reset 会把状态改为需要重建,不会清除坏数据、恢复 Cron 或解决锁。执行前确认影响范围,随后针对性 reindex,并观察是否能回到 Ready。对于大目录,应在维护窗口处理,避免全量索引与营业高峰争用资源。

最终再修改一个商品价格、库存和分类,等待 Cron 自动处理,比较 changelog 与 mview_state version_id 是否追平。只有增量更新连续成功,才说明 suspended 真正恢复。