部署窗口里 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。

