某个禁用商品不在前台展示,catalog_url reindex却每次报重复request_path。禁用状态可能只在某个Store View生效,其他店铺仍启用;再加上历史手工rewrite,就会在同一store_id冲突。

先说结论

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

定位过程

  • 按SKU查看各store_id的status和url_key,不能只看Admin范围。
  • 查询冲突request_path的entity_type、redirect_type和metadata。
mysql -e "SELECT url_rewrite_id,entity_type,entity_id,request_path,target_path,redirect_type,store_id FROM url_rewrite WHERE request_path='example.html';"
bin/magento indexer:reindex catalog_url -vvv
mysql -e "SELECT store_id,value FROM catalog_product_entity_int WHERE entity_id=123 AND attribute_id=(SELECT attribute_id FROM eav_attribute WHERE attribute_code='status' AND entity_type_id=4);"

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

可执行方案

先确定每个Store View期望的唯一URL。删除同一实体、同一店铺的陈旧自动生成记录前做好备份;手工301若占用新路径,改成不冲突的旧路径。然后通过Repository在正确Store Scope保存url_key/status,让Magento重建,不要永久靠SQL插rewrite。

实施时的顺序

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

上线后观察什么

  • 同一store_id+request_path唯一
  • 启用店铺商品返回200
  • 禁用店铺不再生成可访问产品URL
  • catalog_url索引连续两次成功

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

风险点

不同store_id出现相同request_path是允许的,别跨店铺误删。