部署窗口里 setup:upgrade十几分钟没有新输出,最后一行停在Applying data patch。最危险的做法是立刻杀进程并往patch_list插一条记录,因为补丁可能已经改了一半数据。

先判断它是在工作还是在等

ps -ef | grep '[b]in/magento setup:upgrade'
mysql -e 'SHOW FULL PROCESSLIST'
mysql -e 'SHOW ENGINE INNODB STATUS\G'
tail -f var/log/system.log var/log/exception.log

看到大UPDATE持续扫描说明补丁还在工作;状态Waiting for table metadata lock则要找到占锁会话和业务来源。不要先kill升级进程,优先结束不该存在的长事务,并确认其可安全回滚。

找到当前Patch类

用 -vvv在预生产复现。若输出不够,可在部署分支给 PatchApplier增加临时日志,记录apply前后的类名;不要在生产vendor里长期改代码。也可从本次发布新增的DataPatchInterface类开始排查:

grep -R "implements DataPatchInterface" app/code -n
git diff --name-only <last-release>..HEAD | grep -E 'Setup/Patch/Data/.+php$'

检查补丁是否适合大数据

  • 是否一次加载全部collection导致内存增长;
  • 是否在循环内逐条save触发大量Observer和索引;
  • UPDATE条件是否缺索引;
  • 是否调用外部HTTP服务;
  • getDependencies是否形成间接循环。

把大批量修改改成按主键分页,每批提交;补丁必须幂等,重跑时能识别已处理数据。外部API不要放在schema/data patch里。

中断后的恢复原则

先检查业务数据与patch_list。只有确认补丁全部完成、只是写patch_list失败时,才考虑人工登记,并保留SQL证据与发布记录;否则修好补丁后从备份恢复或让幂等逻辑继续执行。

SELECT patch_name FROM patch_list ORDER BY patch_id DESC LIMIT 20;

重新运行前在预生产用生产数据副本计时。上线后检查模块版本、关键数据数量和前台流程,而不只是看到setup:upgrade返回0。