Mysql:在更新查询中使用嵌套的select查询会创建死锁
我正在尝试根据从同一个表中选择的内容更新列。 查询: 有更多的java线程用于从tasks_queue表中拾取 该表的模式如下所示Mysql:在更新查询中使用嵌套的select查询会创建死锁,mysql,database-deadlocks,nested-queries,Mysql,Database Deadlocks,Nested Queries,我正在尝试根据从同一个表中选择的内容更新列。 查询: 有更多的java线程用于从tasks_queue表中拾取 该表的模式如下所示 CREATE TABLE `tasks_queue` ( `id` bigint(18) NOT NULL, `user_id` bigint(18) NOT NULL, `scheduled_at` bigint(13) NOT NULL, `source_type` tinyint(2) NOT NULL, `source_id`
CREATE TABLE `tasks_queue` (
`id` bigint(18) NOT NULL,
`user_id` bigint(18) NOT NULL,
`scheduled_at` bigint(13) NOT NULL,
`source_type` tinyint(2) NOT NULL,
`source_id` bigint(18) DEFAULT NULL,
`priority_level` smallint(6) NOT NULL,
`picked_at` bigint(13) DEFAULT NULL,
`pickup_id` varchar(45) DEFAULT NULL,
`raw_data` longtext NOT NULL,
PRIMARY KEY (`id`),
KEY `scheduled_picked_at_idx` (`scheduled_at`,`picked_at`),
KEY `user_id_idx` (`user_id`),
KEY `pickup_id` (`pickup_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
死锁转储信息
2020-05-27T13:02:53.889027Z 82092 [Note] InnoDB: Transactions deadlock detected, dumping detailed information.
2020-05-27T13:02:53.889048Z 82092 [Note] InnoDB:
*** (1) TRANSACTION:
TRANSACTION 1394376833, ACTIVE 0 sec fetching rows
mysql tables in use 2, locked 2
LOCK WAIT 18 lock struct(s), heap size 1136, 163 row lock(s)
MySQL thread id 80724, OS thread handle 140642529179392, query id 2122809 ip-172-31-29-45.ap-south-1.compute.internal 172.31.29.45 testuser Creating sort index
update tasks_queue as t1, (select id from tasks_queue where (user_id>=1230000000000000) and (user_id<=1230099999999999) and (scheduled_at <= 1590584573882 and picked_at <= 1590583673882) order by priority_level asc, scheduled_at asc limit 0, 1 for update) as t2 set pickup_id = '172.31.29.45-1590584573882-2729', picked_at = 1590584573882 where (user_id>=1230000000000000) and (user_id<=1230099999999999) and (scheduled_at <= 1590584573882 and picked_at <= 1590583673882 and t1.id = t2.id)
2020-05-27T13:02:53.889099Z 82092 [Note] InnoDB: *** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 123642 page no 10 n bits 80 index PRIMARY of table `dspace3`.`tasks_queue` trx id 1394376833 lock_mode X waiting
Record lock, heap no 8 PHYSICAL RECORD: n_fields 12; compact format; info bits 0
0: len 8; hex 80000000074cf829; asc L );;
1: len 6; hex 0000531c807f; asc S ;;
2: len 7; hex c5000001980110; asc ;;
3: len 8; hex 80045eadb112e001; asc ^ ;;
4: len 8; hex 80000172563a7fb4; asc rV: ;;
5: len 1; hex 81; asc ;;
6: len 8; hex 80045eadecadaa6d; asc ^ m;;
7: len 2; hex 8064; asc d;;
8: len 8; hex 8000000000000000; asc ;;
9: SQL NULL;
10: len 8; hex 80045eaded5773fe; asc ^ Ws ;;
11: len 30; hex (total 1126 bytes);
2020-05-27T13:02:53.895025Z 82092 [Note] InnoDB: *** (2) TRANSACTION:
TRANSACTION 1394376831, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
4 lock struct(s), heap size 1136, 3 row lock(s), undo log entries 1
MySQL thread id 82092, OS thread handle 140641975121664, query id 2122814 ip-172-31-29-45.ap-south-1.compute.internal 172.31.29.45 testuser update
insert into tasks_queue (id,user_id,scheduled_at,source_type,source_id,priority_level,raw_data,picked_at) VALUES (-1403646261, 1230000000000001, 1590584573881, 1, 1230001000000109, 100, 'the payload dataa
2020-05-27T13:02:53.895064Z 82092 [Note] InnoDB: *** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 123642 page no 10 n bits 80 index PRIMARY of table `dspace3`.`tasks_queue` trx id 1394376831 lock_mode X locks rec but not gap
Record lock, heap no 8 PHYSICAL RECORD: n_fields 12; compact format; info bits 0
0: len 8; hex 80000000074cf829; asc L );;
1: len 6; hex 0000531c807f; asc S ;;
2: len 7; hex c5000001980110; asc ;;
3: len 8; hex 80045eadb112e001; asc ^ ;;
4: len 8; hex 80000172563a7fb4; asc rV: ;;
5: len 1; hex 81; asc ;;
6: len 8; hex 80045eadecadaa6d; asc ^ m;;
7: len 2; hex 8064; asc d;;
8: len 8; hex 8000000000000000; asc ;;
9: SQL NULL;
10: len 8; hex 80045eaded5773fe; asc ^ Ws ;;
11: len 30; hex test;
2020-05-27T13:02:53.895515Z 82092 [Note] InnoDB: *** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 123642 page no 23 n bits 80 index PRIMARY of table `dspace3`.`tasks_queue` trx id 1394376831 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 11 PHYSICAL RECORD: n_fields 12; compact format; info bits 0
0: len 8; hex 7fffffffac99114e; asc N;;
1: len 6; hex 0000531c807c; asc S |;;
2: len 7; hex c20000c0310266; asc 1 f;;
3: len 8; hex 80045eadb112e001; asc ^ ;;
4: len 8; hex 80000172563a7f93; asc rV: ;;
5: len 1; hex 81; asc ;;
6: len 8; hex 80045eadecadaa6d; asc ^ m;;
7: len 2; hex 8064; asc d;;
8: len 8; hex 8000000000000000; asc ;;
9: SQL NULL;
10: len 8; hex 80045eaded5761ef; asc ^ Wa ;;
11: len 30; hex 4461696c796f6e6c696e654a6f62733c6e6f2d7265706c79406461696c79; asc Daily<no-reply@daily; (total 1125 bytes);
2020-05-27T13:02:53.896735Z 82092 [Note] InnoDB: *** WE ROLL BACK TRANSACTION (2)
有人能解释一下为什么会出现僵局吗
更新:
由于MySQL索引间隙锁定,出现了死锁。update语句中的嵌套select查询将锁定已扫描的记录索引,并锁定索引间隙。我希望这对某人有帮助 锁定是由于使用FOR UPDATE导致的,如果您这样做了会怎么样 参考:
你能解释一下MySQL在执行你建议的查询时使用的锁吗?我不知道,可能只是更新了记录。。。试着阅读我在回答中提供的链接上的信息,也许他们的内容会对你有所帮助。
CREATE TABLE `tasks_queue` (
`id` bigint(18) NOT NULL,
`user_id` bigint(18) NOT NULL,
`scheduled_at` bigint(13) NOT NULL,
`source_type` tinyint(2) NOT NULL,
`source_id` bigint(18) DEFAULT NULL,
`priority_level` smallint(6) NOT NULL,
`picked_at` bigint(13) DEFAULT NULL,
`pickup_id` varchar(45) DEFAULT NULL,
`raw_data` longtext NOT NULL,
PRIMARY KEY (`id`),
KEY `scheduled_picked_at_idx` (`scheduled_at`,`picked_at`),
KEY `user_id_idx` (`user_id`),
KEY `pickup_id` (`pickup_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
2020-05-27T13:02:53.889027Z 82092 [Note] InnoDB: Transactions deadlock detected, dumping detailed information.
2020-05-27T13:02:53.889048Z 82092 [Note] InnoDB:
*** (1) TRANSACTION:
TRANSACTION 1394376833, ACTIVE 0 sec fetching rows
mysql tables in use 2, locked 2
LOCK WAIT 18 lock struct(s), heap size 1136, 163 row lock(s)
MySQL thread id 80724, OS thread handle 140642529179392, query id 2122809 ip-172-31-29-45.ap-south-1.compute.internal 172.31.29.45 testuser Creating sort index
update tasks_queue as t1, (select id from tasks_queue where (user_id>=1230000000000000) and (user_id<=1230099999999999) and (scheduled_at <= 1590584573882 and picked_at <= 1590583673882) order by priority_level asc, scheduled_at asc limit 0, 1 for update) as t2 set pickup_id = '172.31.29.45-1590584573882-2729', picked_at = 1590584573882 where (user_id>=1230000000000000) and (user_id<=1230099999999999) and (scheduled_at <= 1590584573882 and picked_at <= 1590583673882 and t1.id = t2.id)
2020-05-27T13:02:53.889099Z 82092 [Note] InnoDB: *** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 123642 page no 10 n bits 80 index PRIMARY of table `dspace3`.`tasks_queue` trx id 1394376833 lock_mode X waiting
Record lock, heap no 8 PHYSICAL RECORD: n_fields 12; compact format; info bits 0
0: len 8; hex 80000000074cf829; asc L );;
1: len 6; hex 0000531c807f; asc S ;;
2: len 7; hex c5000001980110; asc ;;
3: len 8; hex 80045eadb112e001; asc ^ ;;
4: len 8; hex 80000172563a7fb4; asc rV: ;;
5: len 1; hex 81; asc ;;
6: len 8; hex 80045eadecadaa6d; asc ^ m;;
7: len 2; hex 8064; asc d;;
8: len 8; hex 8000000000000000; asc ;;
9: SQL NULL;
10: len 8; hex 80045eaded5773fe; asc ^ Ws ;;
11: len 30; hex (total 1126 bytes);
2020-05-27T13:02:53.895025Z 82092 [Note] InnoDB: *** (2) TRANSACTION:
TRANSACTION 1394376831, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
4 lock struct(s), heap size 1136, 3 row lock(s), undo log entries 1
MySQL thread id 82092, OS thread handle 140641975121664, query id 2122814 ip-172-31-29-45.ap-south-1.compute.internal 172.31.29.45 testuser update
insert into tasks_queue (id,user_id,scheduled_at,source_type,source_id,priority_level,raw_data,picked_at) VALUES (-1403646261, 1230000000000001, 1590584573881, 1, 1230001000000109, 100, 'the payload dataa
2020-05-27T13:02:53.895064Z 82092 [Note] InnoDB: *** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 123642 page no 10 n bits 80 index PRIMARY of table `dspace3`.`tasks_queue` trx id 1394376831 lock_mode X locks rec but not gap
Record lock, heap no 8 PHYSICAL RECORD: n_fields 12; compact format; info bits 0
0: len 8; hex 80000000074cf829; asc L );;
1: len 6; hex 0000531c807f; asc S ;;
2: len 7; hex c5000001980110; asc ;;
3: len 8; hex 80045eadb112e001; asc ^ ;;
4: len 8; hex 80000172563a7fb4; asc rV: ;;
5: len 1; hex 81; asc ;;
6: len 8; hex 80045eadecadaa6d; asc ^ m;;
7: len 2; hex 8064; asc d;;
8: len 8; hex 8000000000000000; asc ;;
9: SQL NULL;
10: len 8; hex 80045eaded5773fe; asc ^ Ws ;;
11: len 30; hex test;
2020-05-27T13:02:53.895515Z 82092 [Note] InnoDB: *** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 123642 page no 23 n bits 80 index PRIMARY of table `dspace3`.`tasks_queue` trx id 1394376831 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 11 PHYSICAL RECORD: n_fields 12; compact format; info bits 0
0: len 8; hex 7fffffffac99114e; asc N;;
1: len 6; hex 0000531c807c; asc S |;;
2: len 7; hex c20000c0310266; asc 1 f;;
3: len 8; hex 80045eadb112e001; asc ^ ;;
4: len 8; hex 80000172563a7f93; asc rV: ;;
5: len 1; hex 81; asc ;;
6: len 8; hex 80045eadecadaa6d; asc ^ m;;
7: len 2; hex 8064; asc d;;
8: len 8; hex 8000000000000000; asc ;;
9: SQL NULL;
10: len 8; hex 80045eaded5761ef; asc ^ Wa ;;
11: len 30; hex 4461696c796f6e6c696e654a6f62733c6e6f2d7265706c79406461696c79; asc Daily<no-reply@daily; (total 1125 bytes);
2020-05-27T13:02:53.896735Z 82092 [Note] InnoDB: *** WE ROLL BACK TRANSACTION (2)
update
tasks_queue t1
set
pickup_id = '172.31.29.45-1590584573882-2729',
picked_at = 1590584573882
where
(user_id>=1230000000000000)
and
(user_id<=1230099999999999)
and
(scheduled_at <= 1590584573882 and picked_at <= 1590583673882)
and
t1.id in (
select
id
from
tasks_queue
where
(user_id>=1230000000000000)
and
(user_id<=1230099999999999)
and
(scheduled_at <= 1590584573882 and picked_at <= 1590583673882)
order by
priority_level asc, scheduled_at asc
limit
0, 1
)