4

我正在使用 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 是索引键

我怎样才能找到问题的根源?

4

6 回答 6

5

这应该可以解决问题,

复制核心文件:/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 是否之前被处理过,如果是,它不会插入它。它解决了问题..

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

于 2012-08-02T19:58:58.313 回答
3

附加解决方案: -

截断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 索引限制为仅为单独可见的已启用产品创建记录。这很好用。

我希望这会有所帮助!

于 2014-05-02T14:50:09.533 回答
2

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

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

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

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

于 2012-08-02T17:21:47.853 回答
1

我发现 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 reindex 可以正常工作。

运行以下查询会返回一条 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 重写索引已成功重建

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

于 2012-09-02T14:04:21.100 回答
0

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

于 2014-08-22T20:54:45.863 回答
0

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

于 2016-11-05T04:39:52.460 回答