Magento 1.8.1 数据库在 DUPLICATE KEY 上不在 catalog_product_entity_varchar 中进行更新
Magento 1.8.1 database ON DUPLICATE KEY not doing UPDATE in catalog_product_entity_varchar
我认为这可能更像是一个 MySQL 问题而不是 Magento 问题,但这是我正在处理的 Magento 数据库。这是我所做的。
我 MySQL 记录了查询,发现了一个与我即将 post 相似的查询。此查询更新 catalog_product_entity_varchar table
。我把其他正在更新的varchar属性拿出来,只留下有问题的那个,只是为了更容易阅读(有很多属性)。
INSERT INTO `catalog_product_entity_varchar`
(`entity_type_id`,`attribute_id`,`store_id`,`entity_id`,`value`) VALUES
('4', '187', '0', '352203', 'asdf')
ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)
这个查询,无论我是把整个查询放在原始的一堆更多的属性更新中,还是如果我只是像上面那样完全扔进查询中,都不会更新行。上面的确切查询实际上说插入了两行。数据库中的值没有变化。这仅在数据库中与此 table 隔离。没有给出错误。它只是说插入了 x 行。
我决定从另一个类似的实体中提取查询 table。我选择了文本table。该查询如下:
INSERT INTO `catalog_product_entity_text` (`entity_type_id`,`attribute_id`,`store_id`,`entity_id`,`value`)
VALUES ('4', '83', '0', '352203', 'test'), ('4', '106', '0', '352203', 'test')
ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)
按预期工作。因此,我认为这不是 ON DUPLICATE KEY 工作数据库范围内的问题——它与 catalog_product_entity_varchar table.
隔离
我检查了所有 table,没有 table 被锁定或正在使用 。我想也许我必须提交交易,但我不认为这里是这种情况。自动提交已开启。我不相信我可以根据 table 更改它,但我没有使用 START TRANSACTION,所以我无论如何都不必提交,对吗?我在语句后用 COMMIT 进行了测试,甚至认为我 99% 确定它不应该做任何事情,但结果没有改变。
mysql> SHOW VARIABLES LIKE "%autocommit%";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
我决定检查我的开发服务器(是的,这是在生产环境中发生的)并且查询工作得很好。因此,这与 catalog_product_entity_varchar
table 和此特定数据库隔离。
我检查了两个数据库之间的结构,它们是相同的。见下文
开发结构转储
CREATE TABLE IF NOT EXISTS `catalog_product_entity_varchar` (
`value_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Value ID',
`entity_type_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Entity Type ID',
`attribute_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Attribute ID',
`store_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Store ID',
`entity_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Entity ID',
`value` varchar(255) DEFAULT NULL COMMENT 'Value',
PRIMARY KEY (`value_id`),
UNIQUE KEY `UNQ_CAT_PRD_ENTT_VCHR_ENTT_ID_ATTR_ID_STORE_ID` (`entity_id`,`attribute_id`,`store_id`),
KEY `IDX_CATALOG_PRODUCT_ENTITY_VARCHAR_ATTRIBUTE_ID` (`attribute_id`),
KEY `IDX_CATALOG_PRODUCT_ENTITY_VARCHAR_STORE_ID` (`store_id`),
KEY `IDX_CATALOG_PRODUCT_ENTITY_VARCHAR_ENTITY_ID` (`entity_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Catalog Product Varchar Attribute Backend Table' AUTO_INCREMENT=211079 ;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `catalog_product_entity_varchar`
--
ALTER TABLE `catalog_product_entity_varchar`
ADD CONSTRAINT `FK_CATALOG_PRODUCT_ENTITY_VARCHAR_STORE_ID_CORE_STORE_STORE_ID` FOREIGN KEY (`store_id`) REFERENCES `core_store` (`store_id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `FK_CAT_PRD_ENTT_VCHR_ATTR_ID_EAV_ATTR_ATTR_ID` FOREIGN KEY (`attribute_id`) REFERENCES `eav_attribute` (`attribute_id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `FK_CAT_PRD_ENTT_VCHR_ENTT_ID_CAT_PRD_ENTT_ENTT_ID` FOREIGN KEY (`entity_id`) REFERENCES `catalog_product_entity` (`entity_id`) ON DELETE CASCADE ON UPDATE CASCADE;
生产结构转储
CREATE TABLE IF NOT EXISTS `catalog_product_entity_varchar` (
`value_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Value ID',
`entity_type_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Entity Type ID',
`attribute_id` int(10) unsigned NOT NULL COMMENT 'Attribute ID',
`store_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Store ID',
`entity_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Entity ID',
`value` varchar(255) DEFAULT NULL COMMENT 'Value',
PRIMARY KEY (`value_id`),
UNIQUE KEY `UNQ_CAT_PRD_ENTT_VCHR_ENTT_ID_ATTR_ID_STORE_ID` (`entity_id`,`attribute_id`,`store_id`),
KEY `IDX_CATALOG_PRODUCT_ENTITY_VARCHAR_ATTRIBUTE_ID` (`attribute_id`),
KEY `IDX_CATALOG_PRODUCT_ENTITY_VARCHAR_STORE_ID` (`store_id`),
KEY `IDX_CATALOG_PRODUCT_ENTITY_VARCHAR_ENTITY_ID` (`entity_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Catalog Product Varchar Attribute Backend Table' AUTO_INCREMENT=2147483647 ;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `catalog_product_entity_varchar`
--
ALTER TABLE `catalog_product_entity_varchar`
ADD CONSTRAINT `FK_CATALOG_PRODUCT_ENTITY_VARCHAR_STORE_ID_CORE_STORE_STORE_ID` FOREIGN KEY (`store_id`) REFERENCES `core_store` (`store_id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `FK_CAT_PRD_ENTT_VCHR_ATTR_ID_EAV_ATTR_ATTR_ID` FOREIGN KEY (`attribute_id`) REFERENCES `eav_attribute` (`attribute_id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `FK_CAT_PRD_ENTT_VCHR_ENTT_ID_CAT_PRD_ENTT_ENTT_ID` FOREIGN KEY (`entity_id`) REFERENCES `catalog_product_entity` (`entity_id`) ON DELETE CASCADE ON UPDATE CASCADE;
我不知道为什么会这样。我很困惑。
此外,我最近刚刚从备份中恢复了这个数据库,但这是在恢复之前发生的。我正在使用 Percona——最新版本。数据库的设置丢失了,所以我从头开始设置。以下是我认为可能有用的所有设置。
mysql> SHOW VARIABLES LIKE "%version%";
+-------------------------+----------------------------------------------------- -+
| Variable_name | Value |
+-------------------------+----------------------------------------------------- -+
| innodb_version | 5.6.23-72.1 |
| protocol_version | 10 |
| slave_type_conversions | |
| version | 5.6.23-72.1 |
| version_comment | Percona Server (GPL), Release 72.1, Revision 0503478 |
| version_compile_machine | x86_64 |
| version_compile_os | Linux |
+-------------------------+----------------------------------------------------- -+
7 rows in set (0.00 sec)
my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Skip reverse DNS lookup of clients
skip-name-resolve
# optimisations for Magento
# changed open_files_limit to 65535
open_files_limit = 65535
max_allowed_packet = 16M
wait_timeout = 360
# changed kbs from 128M to 32M
key_buffer_size = 32M
# changed query_cache_type = 0 and size to 0
query_cache_type = 1
query_cache_size = 16M
sort_buffer_size = 1M
thread_cache_size = 50
# changed innodb bps to 36G from 20G after RAM upgrade 24GB-48GB
innodb_buffer_pool_size = 39G
# innodb_buffer_pool_instances = 8
innodb_additional_mem_pool_size = 20M
innodb_log_buffer_size = 8M
innodb_file_per_table = 1
innodb_lock_wait_timeout = 1200
ft_min_word_len=2
# Added July 29, 2014
myisam_recover = FORCE,BACKUP
max_connect_errors = 1000000
expire_logs_days = 14
max_connections = 500
table_definition_cache = 4096
table_open_cache = 4096
innodb_flush_method = O_DIRECT
innodb_log_files_in_group = 2
innodb_log_file_size = 512M
innodb_flush_log_at_trx_commit = 1
general_log_file=/var/log/general_log.log
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
好吧,我自己解决。
问题是 table 上的自动递增。它达到了最大值。它使用的是 int(11),因此是 32 位的有符号整数。最大值为 2147483647。
我将其更改为 bigint(12) - 因此,我相信最大数量为 999,999,999,999。
ALTER TABLE `catalog_product_entity_varchar`
CHANGE `value_id` `value_id` BIGINT( 12 )
NOT NULL AUTO_INCREMENT COMMENT 'Value ID';
这应该没问题,因为没有外键使用该字段。我认为如果有外键使用它,您可能还需要更改它们以反映相同的数据类型。
我认为这可能更像是一个 MySQL 问题而不是 Magento 问题,但这是我正在处理的 Magento 数据库。这是我所做的。
我 MySQL 记录了查询,发现了一个与我即将 post 相似的查询。此查询更新 catalog_product_entity_varchar table
。我把其他正在更新的varchar属性拿出来,只留下有问题的那个,只是为了更容易阅读(有很多属性)。
INSERT INTO `catalog_product_entity_varchar`
(`entity_type_id`,`attribute_id`,`store_id`,`entity_id`,`value`) VALUES
('4', '187', '0', '352203', 'asdf')
ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)
这个查询,无论我是把整个查询放在原始的一堆更多的属性更新中,还是如果我只是像上面那样完全扔进查询中,都不会更新行。上面的确切查询实际上说插入了两行。数据库中的值没有变化。这仅在数据库中与此 table 隔离。没有给出错误。它只是说插入了 x 行。
我决定从另一个类似的实体中提取查询 table。我选择了文本table。该查询如下:
INSERT INTO `catalog_product_entity_text` (`entity_type_id`,`attribute_id`,`store_id`,`entity_id`,`value`)
VALUES ('4', '83', '0', '352203', 'test'), ('4', '106', '0', '352203', 'test')
ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)
按预期工作。因此,我认为这不是 ON DUPLICATE KEY 工作数据库范围内的问题——它与 catalog_product_entity_varchar table.
隔离我检查了所有 table,没有 table 被锁定或正在使用 。我想也许我必须提交交易,但我不认为这里是这种情况。自动提交已开启。我不相信我可以根据 table 更改它,但我没有使用 START TRANSACTION,所以我无论如何都不必提交,对吗?我在语句后用 COMMIT 进行了测试,甚至认为我 99% 确定它不应该做任何事情,但结果没有改变。
mysql> SHOW VARIABLES LIKE "%autocommit%";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
我决定检查我的开发服务器(是的,这是在生产环境中发生的)并且查询工作得很好。因此,这与 catalog_product_entity_varchar
table 和此特定数据库隔离。
我检查了两个数据库之间的结构,它们是相同的。见下文
开发结构转储
CREATE TABLE IF NOT EXISTS `catalog_product_entity_varchar` (
`value_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Value ID',
`entity_type_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Entity Type ID',
`attribute_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Attribute ID',
`store_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Store ID',
`entity_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Entity ID',
`value` varchar(255) DEFAULT NULL COMMENT 'Value',
PRIMARY KEY (`value_id`),
UNIQUE KEY `UNQ_CAT_PRD_ENTT_VCHR_ENTT_ID_ATTR_ID_STORE_ID` (`entity_id`,`attribute_id`,`store_id`),
KEY `IDX_CATALOG_PRODUCT_ENTITY_VARCHAR_ATTRIBUTE_ID` (`attribute_id`),
KEY `IDX_CATALOG_PRODUCT_ENTITY_VARCHAR_STORE_ID` (`store_id`),
KEY `IDX_CATALOG_PRODUCT_ENTITY_VARCHAR_ENTITY_ID` (`entity_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Catalog Product Varchar Attribute Backend Table' AUTO_INCREMENT=211079 ;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `catalog_product_entity_varchar`
--
ALTER TABLE `catalog_product_entity_varchar`
ADD CONSTRAINT `FK_CATALOG_PRODUCT_ENTITY_VARCHAR_STORE_ID_CORE_STORE_STORE_ID` FOREIGN KEY (`store_id`) REFERENCES `core_store` (`store_id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `FK_CAT_PRD_ENTT_VCHR_ATTR_ID_EAV_ATTR_ATTR_ID` FOREIGN KEY (`attribute_id`) REFERENCES `eav_attribute` (`attribute_id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `FK_CAT_PRD_ENTT_VCHR_ENTT_ID_CAT_PRD_ENTT_ENTT_ID` FOREIGN KEY (`entity_id`) REFERENCES `catalog_product_entity` (`entity_id`) ON DELETE CASCADE ON UPDATE CASCADE;
生产结构转储
CREATE TABLE IF NOT EXISTS `catalog_product_entity_varchar` (
`value_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Value ID',
`entity_type_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Entity Type ID',
`attribute_id` int(10) unsigned NOT NULL COMMENT 'Attribute ID',
`store_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Store ID',
`entity_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Entity ID',
`value` varchar(255) DEFAULT NULL COMMENT 'Value',
PRIMARY KEY (`value_id`),
UNIQUE KEY `UNQ_CAT_PRD_ENTT_VCHR_ENTT_ID_ATTR_ID_STORE_ID` (`entity_id`,`attribute_id`,`store_id`),
KEY `IDX_CATALOG_PRODUCT_ENTITY_VARCHAR_ATTRIBUTE_ID` (`attribute_id`),
KEY `IDX_CATALOG_PRODUCT_ENTITY_VARCHAR_STORE_ID` (`store_id`),
KEY `IDX_CATALOG_PRODUCT_ENTITY_VARCHAR_ENTITY_ID` (`entity_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Catalog Product Varchar Attribute Backend Table' AUTO_INCREMENT=2147483647 ;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `catalog_product_entity_varchar`
--
ALTER TABLE `catalog_product_entity_varchar`
ADD CONSTRAINT `FK_CATALOG_PRODUCT_ENTITY_VARCHAR_STORE_ID_CORE_STORE_STORE_ID` FOREIGN KEY (`store_id`) REFERENCES `core_store` (`store_id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `FK_CAT_PRD_ENTT_VCHR_ATTR_ID_EAV_ATTR_ATTR_ID` FOREIGN KEY (`attribute_id`) REFERENCES `eav_attribute` (`attribute_id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `FK_CAT_PRD_ENTT_VCHR_ENTT_ID_CAT_PRD_ENTT_ENTT_ID` FOREIGN KEY (`entity_id`) REFERENCES `catalog_product_entity` (`entity_id`) ON DELETE CASCADE ON UPDATE CASCADE;
我不知道为什么会这样。我很困惑。
此外,我最近刚刚从备份中恢复了这个数据库,但这是在恢复之前发生的。我正在使用 Percona——最新版本。数据库的设置丢失了,所以我从头开始设置。以下是我认为可能有用的所有设置。
mysql> SHOW VARIABLES LIKE "%version%";
+-------------------------+----------------------------------------------------- -+
| Variable_name | Value |
+-------------------------+----------------------------------------------------- -+
| innodb_version | 5.6.23-72.1 |
| protocol_version | 10 |
| slave_type_conversions | |
| version | 5.6.23-72.1 |
| version_comment | Percona Server (GPL), Release 72.1, Revision 0503478 |
| version_compile_machine | x86_64 |
| version_compile_os | Linux |
+-------------------------+----------------------------------------------------- -+
7 rows in set (0.00 sec)
my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Skip reverse DNS lookup of clients
skip-name-resolve
# optimisations for Magento
# changed open_files_limit to 65535
open_files_limit = 65535
max_allowed_packet = 16M
wait_timeout = 360
# changed kbs from 128M to 32M
key_buffer_size = 32M
# changed query_cache_type = 0 and size to 0
query_cache_type = 1
query_cache_size = 16M
sort_buffer_size = 1M
thread_cache_size = 50
# changed innodb bps to 36G from 20G after RAM upgrade 24GB-48GB
innodb_buffer_pool_size = 39G
# innodb_buffer_pool_instances = 8
innodb_additional_mem_pool_size = 20M
innodb_log_buffer_size = 8M
innodb_file_per_table = 1
innodb_lock_wait_timeout = 1200
ft_min_word_len=2
# Added July 29, 2014
myisam_recover = FORCE,BACKUP
max_connect_errors = 1000000
expire_logs_days = 14
max_connections = 500
table_definition_cache = 4096
table_open_cache = 4096
innodb_flush_method = O_DIRECT
innodb_log_files_in_group = 2
innodb_log_file_size = 512M
innodb_flush_log_at_trx_commit = 1
general_log_file=/var/log/general_log.log
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
好吧,我自己解决。
问题是 table 上的自动递增。它达到了最大值。它使用的是 int(11),因此是 32 位的有符号整数。最大值为 2147483647。
我将其更改为 bigint(12) - 因此,我相信最大数量为 999,999,999,999。
ALTER TABLE `catalog_product_entity_varchar`
CHANGE `value_id` `value_id` BIGINT( 12 )
NOT NULL AUTO_INCREMENT COMMENT 'Value ID';
这应该没问题,因为没有外键使用该字段。我认为如果有外键使用它,您可能还需要更改它们以反映相同的数据类型。