某个禁用商品不在前台展示,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是允许的,别跨店铺误删。

