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';

这应该没问题,因为没有外键使用该字段。我认为如果有外键使用它,您可能还需要更改它们以反映相同的数据类型。