【问题标题】:Constraint violation / Duplicate key when reindexing Magento重新索引 Magento 时违反约束/重复键
【发布时间】:2012-07-31 15:38:19
【问题描述】:

我正在使用 Magento CE 1.6.2,但我的重新索引器(url_rewrite)有问题

php shell/indexer.php --reindex catalog_url
Catalog URL Rewrites index process unknown error:
exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '33432700_1343855802-0-1' for key 'UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID'' in /home/website/public_html/lib/Zend/Db/Statement/Pdo.php:228

当我第一次截断 core_url_rewrite... 并通过后端访问索引器时,一切都很好,我的 url 重写存储在 core_url_rewrites... 但是如果我第二次启动索引器(不刷新表),我会收到重复键的错误。

这是我的桌子的屏幕截图:https://www.dropbox.com/s/6v9uawp5v437w3h/seo_Magewroks.png

注意:UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID 是索引键

如何找到问题的根源?

【问题讨论】:

    标签: magento pdo duplicates constraints zend-db


    【解决方案1】:

    第一次工作,但在随后的重新索引中失败似乎有点不寻常。您确定您使用的是 InnoDB 并且您的 MySQL 设置正确吗?我会检查以确保您的 innodb 缓存足够大,并查看 MySQL 本身是否会吐出任何类型的错误。 Magento 充分利用了 InnoDB 的事务查询,如果 MySQL 内存或空间不足来存储此类大型事务中准备好的查询,您可能会遇到问题。

    您遇到的错误具有误导性,因为在第一次构建表时,会在第一次重新索引时捕获到重复的键。如果这是一个简单的数据问题,例如重复的 SKU 或不正确的类别层次结构,那么索引将在第一次尝试时失败。

    您可能还想确保您的应用程序的 MySQL 用户有足够的权限在必要时刷新表。 Magento 会想破坏桌子;如果不能,它可能会尝试重新构建,从而导致重复键错误。

    我也会尝试tail 您的exception.log 文件,看看您是否可以获得堆栈跟踪并将其发布在此处。此外,尝试为 MySQL 库启用调试日志记录(您可以在 /lib/Varien/Db/Adapter/Pdo/Mysql.php 的第 103 行将 $_debug 的默认值更改为 true - 您可能还希望将 $_logAllQueries$_logCallStack 更改为 true以及)。在$_debugFile 中查找tail 的路径。

    【讨论】:

    • Georges(我的同事)找到了解决方法,但我们仍然不明白是什么导致了问题。
    • 我遇到了同样的问题。堆栈跟踪包括如 OP 所述,后跟类似于 link。当我清除 core_url_rewrite 表并重新索引一次它工作时,第二次它发出吱吱声。重复的条目每次都不同,但总是以 -0-1 结尾。您会推荐哪些 MySql 设置?我正在运行一个包含大约一百种产品的本地 xampp?
    【解决方案2】:

    这应该可以解决问题,

    复制核心文件:/app/code/core/Mage/Catalog/Model/Resource/Url.php 到:/app/code/local/Mage/Catalog/Model/Resource/Url.php

    找到这个函数:

    public function saveRewriteHistory($rewriteData)
    {
        $rewriteData = new Varien_Object($rewriteData);
        // check if rewrite exists with save request_path
        $rewrite = $this->getRewriteByRequestPath($rewriteData->getRequestPath(), $rewriteData->getStoreId());
    
        if ($rewrite === false) {
            // create permanent redirect
            $this->_getWriteAdapter()->insert($this->getMainTable(), $rewriteData->getData());
        }
    
        return $this;
    
    }
    

    替换为:

    protected $_processedRewrites = array();   // add this to your class vars on top
    
    public function saveRewriteHistory($rewriteData)
    {
        $rewriteData = new Varien_Object($rewriteData);
        // check if rewrite exists with save request_path
        $rewrite = $this->getRewriteByRequestPath($rewriteData->getRequestPath(), $rewriteData->getStoreId());
        $data = $rewriteData->getData();
    
        $current = $data["id_path"]."_".$data["is_system"]."_".$data["store_id"];
        if ($rewrite === false && !in_array($current, $this->_processedRewrites)) {
            $this->_processedRewrites[] = $current;
            // create permanent redirect
            $this->_getWriteAdapter()->insert($this->getMainTable(), $rewriteData->getData());
        }
    
        return $this;
    }
    

    问题是因为函数检查数据库以查看在插入之前是否在 core_url_rewrites 中存在重写。这很好。但它使用以下属性进行检查: request_path, is_system, store_id

    我们的问题是有些行重复了 id_path 但有不同的 request_path……这很奇怪,不知道为什么不应该这样……

    但是使用这个替换功能,它还会检查 id_path 之前是否已处理,如果是,则不会插入它。它解决了问题..

    但是,我们仍然不知道问题的根源

    【讨论】:

    • 伙计,你摇滚我一直在寻找 DAYS 来解决这个问题。我已经在阳光下尝试了所有方法,包括截断 core_url 表和许多其他表。您是否能够找到源头的问题?谢谢你!
    【解决方案3】:

    我发现 db 用户具有正确的权限,并且我不喜欢更改核心代码,无论它是否移动到本地。

    从 1.4 升级到 1.6 后,在命令行重新索引后遇到错误。

    php indexer.php -reindex catalog_url
    An error occurred while saving the URL rewrite
    

    与日志中的以下异常配对:-

    exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'category/360-1-6' for key 'UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID'' in httpdocs/lib/Zend/Db/Statement/Pdo.php:228
    

    我通过 mysql 运行以下查询以定位问题记录(注意查询与异常的关系),它与已重命名的类别有关...

    QUERY: select * from core_url_rewrite where id_path =  "category/360";
    

    我注意到这是一个类别 url 重写,并且 product_id 记录是 0 而不是 NULL,我怀疑这是问题所在,如果您遇到此问题,看看这对您来说是否相同会很有趣,运行以下命令:

    QUERY: select * from core_url_rewrite where product_id=0;
    

    当我运行上述查询时,它返回了一条问题记录。

    我找到的解决方法是删除问题记录...

    现在 catalog_url 重新索引可以正常工作。

    运行以下查询会返回一条 product_id 为 NULL 的新记录,并表示新的 URI 路径。旧的 URI 会导致 404,而不是应该做的重定向。

    QUERY: select * from core_url_rewrite where id_path =  "category/360";
    

    我相信这个问题是一个单一的数据记录问题,可能是在升级之后。我不同意更改 URL.php 或截断 core_url_rewrite 是正确的。

    我已经为 catalog_url 重建了两次索引,第三次作为完整重建索引的一部分。全部返回:目录 URL 重写索引已成功重建

    我已经记录了我的发现,您的情况可能有所不同,但这有助于解释您如何找到问题并解决它。

    【讨论】:

      【解决方案4】:

      其他解决方案:-

      当截断 core_url_rewrite 表时,您将丢失所有旧版 url 密钥更改传播记录。我发现删除所有标记为“is_system”1 的记录将保留这些旧版 url 重定向,请使用查询:-

      DELETE FROM `core_url_rewrite` WHERE `is_system` = 1;
      

      这与截断表格的影响相同,同时保持您可能创建的 url 更改传播或定制重定向。

      正如 Alan Storm 解释的那样:-

      is_system 属性可能更准确地命名为 is_canonical_rewrite_for_category_or_product_category_combo。也就是说,is_system,是 Magento 设置的一个布尔标志,让自己知道哪些行是系统级重写的,由 Magento 创建,并且当前表示特定实体的“主”URL(而不是重定向重写,它们也是由系统创建的,但它们的 is_system 标志设置为 false)。艾伦风暴 - http://alanstorm.com/

      此外,如果您可以将损坏范围缩小到产品或类别记录,您可以使用以下方法:-

      维护类别重定向:-

      DELETE FROM `core_url_rewrite` WHERE `is_system` = 1 AND `category_id` IS NOT NULL;
      

      维护产品重定向:-

      DELETE FROM `core_url_rewrite` WHERE `is_system` = 1 AND `product_id` IS NOT NULL;
      

      请记住,所有标记为 is_system 1 的记录都是 Magento 根据产品或类别数据创建的,并且可以重新创建。标记为 is_system 0 的记录在其他任何地方都不存在,如果您只是截断 core_url_rewrite,将永远丢失来自其他站点的“死胡同”旧链接。

      另一个有影响的问题是 Magneto 在重新索引时尝试创建的 URL 重定向数量。如果您有大量产品使用以下扩展可以加快索引时间并减少 core_url_rewrite 表中的记录数:- http://www.magentocommerce.com/magento-connect/dn-d-patch-index-url-1.html

      Dn'D 补丁索引 URL 扩展将 URL 索引限制为仅为单独可见的已启用产品创建记录。这很好用。

      希望对大家有所帮助!

      【讨论】:

        【解决方案5】:

        不知道是什么导致我们的网站出现这种情况,但解决方法很简单。如果您不关心旧的 URL 重定向(例如,您的产品 URL 一直是它们现在的样子,或者您不关心丢失历史记录)截断 core_url_rewrite 表,然后重新索引。

        【讨论】:

          【解决方案6】:

          最简单的解决方案是从 core_url_rewrite 表中删除这些记录并重新索引

          【讨论】:

            猜你喜欢
            • 2019-05-03
            • 2011-05-25
            • 2020-07-22
            • 1970-01-01
            • 1970-01-01
            • 2022-01-13
            • 2020-03-27
            • 2013-06-23
            相关资源
            最近更新 更多