升级扩展后功能已经是新代码,module:status也显示启用,但数据库里的版本号没变,甚至旧安装脚本没有再执行。这个现象通常不是缓存,而是把声明式Schema/Data Patch与旧式setup_version混在一起判断了。

先把现象钉死

先用一个真实失败样本复现,不要一上来全量重建。把请求、实体ID和时间记下来,后面的SQL与日志才能对得上。

现场检查

  • 先确认模块注册名与composer包名不是一回事,真正写入setup_module的是registration.php里的模块名。
  • Magento 2.3以后Data Patch是否执行看patch_list,不再靠setup_version递增。
bin/magento module:status Vendor_Module
mysql -e "SELECT module,schema_version,data_version FROM setup_module WHERE module='Vendor_Module';"
mysql -e "SELECT patch_name FROM patch_list WHERE patch_name LIKE 'Vendor\\Module\\Setup\\Patch\\Data%';"
bin/magento setup:upgrade -vvv

为了避免把环境差异当成根因,我会先在预发布或数据库副本复现;涉及订单、库存和支付的操作,正式环境只做只读核对,修复脚本必须带明确的订单号或SKU范围。

实际修复

如果是Data Patch,给补丁类增加正确的getDependencies()/getAliases(),不要为了重跑直接改版本号。测试库可在备份后删除那一条patch_list记录再执行;生产库应新建一个幂等Patch,在apply()里先查询再更新。若仍使用UpgradeData,才需要同步修改module.xml的setup_version并检查setup_module记录。

实施时的顺序

  • 先做数据与配置备份,记录当前值。
  • 只改一个变量并重跑失败样本。
  • 确认新数据正确后,再处理历史受影响记录。
  • 最后恢复定时任务或缓存。

怎么确认没有假好

  • setup:upgrade输出明确出现补丁类名
  • patch_list新增记录且业务数据只写入一次
  • 连续再跑一次setup:upgrade没有重复数据

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

留一个坑位提醒

不要整表清空patch_list,这会让所有历史补丁被重新判定,后果比版本号不变严重得多。

如果线上数据已经不一致,先停掉会继续扩大差异的入口,再修历史数据;否则一边补一边写,最后很难判断哪些记录已经处理。