MySQL 并发批量删除数据死锁问题
问题描述
在生产中有一条批量删除的 SQL,当并发量达到一定量后经常出现死锁问题。
本文首先在本地还原场景,然后简化模型,在简化模型上测试和验证,从而分析 MySQL 的机制以及问题出现的根因。最终得到解决方案,并在原场景中得到验证。
场景还原
DDL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CREATE TABLE `store_sku_stock` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`parent_store_id` varchar(64) NOT NULL COMMENT '父门店编号',
`store_id` varchar(64) NOT NULL COMMENT '门店编号',
`sku` varchar(64) NOT NULL COMMENT '商品sku',
`avail_qty` int(11) DEFAULT '0' COMMENT '库存数量',
`source_qty` int(11) DEFAULT '0' COMMENT 'DP下发库存',
`safety_qty` int(11) DEFAULT '0' COMMENT '安全库存',
`type` tinyint(4) NOT NULL COMMENT '1:当日库存,2.隔日库存',
`avail_date` datetime DEFAULT NULL COMMENT '有效时间',
`dp_uuid` varchar(64) DEFAULT NULL COMMENT 'uuid',
`create_date` datetime DEFAULT NULL COMMENT '创建时间',
`update_date` datetime DEFAULT NULL COMMENT '修改时间',
`create_user` varchar(16) DEFAULT NULL COMMENT '创建人',
`update_user` varchar(16) DEFAULT NULL COMMENT '修改人',
`stock_status` tinyint(4) DEFAULT '0' COMMENT '库存状态(0:售罄,1:库存紧张,2:库存充足)',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_store_id_sku` (`store_id`,`sku`,`type`,`avail_date`) USING BTREE,
KEY `idx_sku` (`sku`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=292839494 DEFAULT CHARSET=utf8 COMMENT='门店商品库存';
create unique index idx_store_id_sku on store_sku_stock(store_id, sku, type, avail_date) using btree;还原现场用的测试数据:需要多条数据,预计10000条。然后随机选择两次批量删除的
验证方案
验证死锁原因
测试数据:只需要演示两条数据 sku a,b、门店都是1、日期同一天2020-01-01、类型相同1.
1
2
3
4
5
6
7
insert into store_sku_stock values (
1, '1', '1', 'a', 1, 1, 1, 1, '2020-01-01 00:00:00', '1', '2020-01-01 00:00:00', '2020-01-01 00:00:00', '1', '1', 1
);
insert into store_sku_stock values (
2, '1', '1', 'b', 1, 1, 1, 1, '2020-01-01 00:00:00', '1', '2020-01-01 00:00:00', '2020-01-01 00:00:00', '1', '1', 1
);