我正在尝试帮助客户端解决MySql数据库死锁问题。这些死锁似乎导致API调用需要10-30秒。我在API调用上重试逻辑至少尝试3次。但是,我的应用程序在3次API调用后仍然失败,大部分时间都是由于死锁。
我打印出了显示引擎innodb状态'。我已经改进了一些看似困扰Magento安装的magento查询。我仍然有这个似乎在大部分时间都在弹出状态的那个。我清除了缓存,截断日志表,并删除了超过60天的sales_flat_quote。
我会指出这个MySql版本是5.1。我想告诉客户他们应该升级到5.5,这会解决大部分问题吗?
我注意到这个僵局是锁定没有意义。第二次交易不应该与该指数有关(在我看来)。
这是Magento Enterprise 1.12.1。
=====================================
140317 14:02:19 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 3 seconds
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 126213527, signal count 95958876
Mutex spin waits 0, rounds 23717002258, OS waits 75872845
RW-shared spins 28395611, OS waits 6711740; RW-excl spins 47024915, OS waits 2065225
------------------------
LATEST FOREIGN KEY ERROR
------------------------
140317 12:00:01 Cannot truncate table `testcom_testcom_migration`.`catalogsearch_query` by DROP+CREATE
InnoDB: because it is referenced by `testcom_testcom_migration`.`bss_cms_result`
------------------------
LATEST DETECTED DEADLOCK
------------------------
140317 14:02:07
*** (1) TRANSACTION:
TRANSACTION 0 496858972, ACTIVE 1 sec, process no 6717, OS thread id 139831325689600 starting index read
mysql tables in use 1, locked 1
LOCK WAIT 23 lock struct(s), heap size 3024, 12 row lock(s), undo log entries 10
MySQL thread id 1260454, query id 109805416 localhost testcom_new updating
DELETE FROM `catalogrule_product_price` WHERE (product_id='12216')
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 846908 n bits 1272 index `IDX_CATALOGRULE_PRODUCT_PRICE_PRODUCT_ID` of table `testcom_testcom_migration`.`catalogrule_product_price` trx id 0 496858972 lock_mode X waiting
Record lock, heap no 252 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 00002fb8; asc / ;; 1: len 4; hex 001abcde; asc ;;
*** (2) TRANSACTION:
TRANSACTION 0 496858674, ACTIVE 8 sec, process no 6717, OS thread id 139831333410560 starting index read, thread declared inside InnoDB 500
mysql tables in use 1, locked 1
11259 lock struct(s), heap size 1013744, 561072 row lock(s), undo log entries 48
MySQL thread id 1260440, query id 109805651 localhost testcom_new Updating
UPDATE `index_process` SET `status` = 'require_reindex' WHERE (process_id='9')
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 0 page no 846908 n bits 1272 index `IDX_CATALOGRULE_PRODUCT_PRICE_PRODUCT_ID` of table `testcom_testcom_migration`.`catalogrule_product_price` trx id 0 496858674 lock mode S
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;
Record lock, heap no 2 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 00002df7; asc - ;; 1: len 4; hex 001abbf7; asc ;;
Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 00002df7; asc - ;; 1: len 4; hex 001abbf8; asc ;;
....
....
....
etc....
其他信息
SHOW CREATE TABLE index_process
CREATE TABLE `index_process` (
`process_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Process Id',
`indexer_code` varchar(32) NOT NULL COMMENT 'Indexer Code',
`status` varchar(15) NOT NULL DEFAULT 'pending' COMMENT 'Status',
`started_at` timestamp NULL DEFAULT NULL COMMENT 'Started At',
`ended_at` timestamp NULL DEFAULT NULL COMMENT 'Ended At',
`mode` varchar(9) NOT NULL DEFAULT 'real_time' COMMENT 'Mode',
PRIMARY KEY (`process_id`),
UNIQUE KEY `UNQ_INDEX_PROCESS_INDEXER_CODE` (`indexer_code`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 COMMENT='Index Process'
SHOW CREATE TABLE catalogrule_product_price
CREATE TABLE `catalogrule_product_price` (
`rule_product_price_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Rule Product PriceId',
`rule_date` date NOT NULL DEFAULT '0000-00-00' COMMENT 'Rule Date',
`customer_group_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Customer Group Id',
`product_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Product Id',
`rule_price` decimal(12,4) NOT NULL DEFAULT '0.0000' COMMENT 'Rule Price',
`website_id` smallint(5) unsigned NOT NULL COMMENT 'Website Id',
`latest_start_date` date DEFAULT NULL COMMENT 'Latest StartDate',
`earliest_end_date` date DEFAULT NULL COMMENT 'Earliest EndDate',
PRIMARY KEY (`rule_product_price_id`),
UNIQUE KEY `UNQ_CATRULE_PRD_PRICE_RULE_DATE_WS_ID_CSTR_GROUP_ID_PRD_ID` (`rule_date`,`website_id`,`customer_group_id`,`product_id`),
KEY `IDX_CATALOGRULE_PRODUCT_PRICE_CUSTOMER_GROUP_ID` (`customer_group_id`),
KEY `IDX_CATALOGRULE_PRODUCT_PRICE_WEBSITE_ID` (`website_id`),
KEY `IDX_CATALOGRULE_PRODUCT_PRICE_PRODUCT_ID` (`product_id`),
CONSTRAINT `FK_CATALOGRULE_PRODUCT_PRICE_WEBSITE_ID_CORE_WEBSITE_WEBSITE_ID` FOREIGN KEY (`website_id`) REFERENCES `core_website` (`website_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_CATRULE_PRD_PRICE_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID` FOREIGN KEY (`customer_group_id`) REFERENCES `customer_group` (`customer_group_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_CATRULE_PRD_PRICE_PRD_ID_CAT_PRD_ENTT_ENTT_ID` FOREIGN KEY (`product_id`) REFERENCES `catalog_product_entity` (`entity_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1805881 DEFAULT CHARSET=utf8 COMMENT='CatalogRule Product Price'
答案 0 :(得分:1)
不是查询,但事务(!)确实存在冲突。事务2在catalogrule_product_price
上拥有共享锁。事务1尝试更新catalogrule_product_price
并需要一个独占锁。锁定。
由于您删除了日志事务2的下半部分,我们无法看到更多详细信息以及最终导致死锁的原因。请提供完整的日志。
顺便说一下,交易2的运行时间相当长。它已经激活8秒,并锁定相同的时间。这对应用程序来说并不好。您可能希望阅读coping with deadlocks上的提示,这些提示基本上应该通过更改查询执行来尝试避免死锁。
其中列出的另一个提示是使用较低的隔离级别,提及READ COMMITTED
,但我认为这对此没有帮助(但你应该试一试!)。
您应该仔细查看长时间运行的事务(以及相应的脚本)正在执行的操作。搜索此更新查询的代码
UPDATE `index_process` SET `status` = 'require_reindex' WHERE (process_id='9')
并分析相应脚本的作用。
您的主要问题是此脚本长时间锁定行(产品价格行),这可能会在您的应用程序中广泛使用。为了避免这种情况,您可以通过将事务隔离级别设置为READ UNCOMMITTED
来避免它获取的共享锁,但要理解what it means to set this transaction level。此脚本可能会使用旧数据。如果你能负担得起这个缺点,这可能会解决你的问题。
正在更新 MySQL很可能无法解决您的问题。死锁不依赖于版本。 (但是你可能想要更新,因为从5.1到5.5有一些严重的执行改进。例如关于优化器。)