问题 Magento 1.4.0升级到1.6.2.0的唯一约束违规


我正在现有的Magento网站上进行升级。大约10分钟后,Magento报告异常,当我检查/ var / report中的错误报告文件时,我看到以下错误消息和堆栈转储:

a:5:{i:0;s:223:"Error in file: "/var/www/vhosts/mymagesite/app/code/core/Mage/Customer/sql/customer_setup/mysql4-upgrade-1.5.9.9-1.6.0.0.php" - SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '0-8' for key 'UNQ_BY_CUSTOMER'";i:1;s:952:"#0 /var/www/vhosts/mymagesite/app/code/core/Mage/Core/Model/Resource/Setup.php(645): Mage::exception('Mage_Core', 'Error in file: ...')
#1 /var/www/vhosts/mymagesite/app/code/core/Mage/Core/Model/Resource/Setup.php(437): Mage_Core_Model_Resource_Setup->_modifyResourceDb('upgrade', '1.4.0.0.7', '1.6.1.0')
#2 /var/www/vhosts/mymagesite/app/code/core/Mage/Core/Model/Resource/Setup.php(320): Mage_Core_Model_Resource_Setup->_upgradeResourceDb('1.4.0.0.7', '1.6.1.0')
#3 /var/www/vhosts/mymagesite/app/code/core/Mage/Core/Model/Resource/Setup.php(235): Mage_Core_Model_Resource_Setup->applyUpdates()
#4 /var/www/vhosts/mymagesite/app/code/core/Mage/Core/Model/App.php(412): Mage_Core_Model_Resource_Setup::applyAllUpdates()
#5 /var/www/vhosts/mymagesite/app/code/core/Mage/Core/Model/App.php(338): Mage_Core_Model_App->_initModules()
#6 /var/www/vhosts/mymagesite/app/Mage.php(640): Mage_Core_Model_App->run(Array)
#7 /var/www/vhosts/mymagesite/index.php(80): Mage::run('default', 'store')
#8 {main}";s:3:"url";s:16:"/index.php/admin";s:11:"script_name";s:10:"/index.php";s:4:"skin";s:7:"default";}

互联网上其他地方的一般建议是改变 <initStatements> 在 app/etc/config.xml 读书:

<initStatements>SET NAMES utf8; SET FOREIGN_KEY_CHECKS=0; SET UNIQUE_CHECKS=0;</initStatements>

但是,禁用数据库完整性约束系统是以后难以支持和解决问题的保证路径。这是一个黑客,使升级脚本不会因错误而崩溃,它实际上并没有以任何方式解决问题的形状或形式。

StackOverflow社区是否可以帮助提供更好的解决方案,或者为什么在MySQL中禁用完整性检查是一个好主意?


12273
2018-02-03 05:08


起源

禁用所有扩展程序在升级时恢复为默认主题? - Anton S
我没有禁用扩展程序或恢复默认主题。我不确定如何解决这个问题。如果第三方扩展导致此错误,则已对数据库执行“损坏”并禁用它们将不会撤消它。 - Jim OHalloran
嘿吉姆:)你应该禁用它们的原因是扩展通常的工作方式。 Magento方式是扩展和重写,如果你需要改变一些东西,扩展正在重写某些版本的magento并且没有将它更新到最新版本。所以基本上错误是扩展重写了一些东西,而magento已经更新了这部分=冲突 - Anton S
啊,好吧......我现在明白了。 - Jim OHalloran


答案:


这个表可以截断。 http://docs.nexcess.net/magento-database-maintenance

它是收集站点使用信息的一小组表之一,这些信息对于magento的操作并不重要。 (如果您使用这些报告,它确实会影响客户报告。)

问题出在以下迁移脚本中:

/app/code/core/Mage/Customer/sql/customer_setup/mysql4-upgrade-1.5.9.9-1.6.0.0.php

它改变了一个用于默认为NULL的列,默认为非null。

ALTER TABLE `report_compared_product_index` MODIFY COLUMN `customer_id` int UNSIGNED NOT NULL COMMENT ''

该错误来自该列的唯一索引。之前它是null,所以MySQL忽略了唯一索引。一旦将其设置为默认值为非null,NULL就不再是有效值,并且它会尝试将列的值设置为0.它会到达第二行,现在它会打破唯一索引,并且会出现错误, http://bugs.mysql.com/bug.php?id=8173

1.4x代码在此表中保存了与新模式不兼容的数据。 它也很难清理,因为缺少的信息需要满足唯一索引。 最快的选择是截断表格。


12
2018-01-18 20:02



谢谢@txyoji,这是一个很好的答案。 - Jim OHalloran


这相对容易从错误消息中解密。您有一个重复的客户(或多个重复的客户)。

在phpMyadmin中打开您的customer_entity表并查找重复项。根据您可能需要手动完成的客户数量,可能会使用'fred@test.com'样式的电子邮件从您自己的测试中获得重复项。一旦你完成了表格,你就应该能够安全地删除这些内容,然后自己解决这些问题。


0
2018-02-29 11:41



我能够通过从命令行运行更新来克服这个问题(即“php index.php”)。如果数据库中存在真正重复的记录,无论是从浏览器还是命令行运行更新,我都应该看到相同的错误消息。 - Jim OHalloran