Я пытаюсь обновить столбцы на основе выбора из той же таблицы. Запрос:
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)
и попытка извлечь запись с помощью следующего запроса.
select raw_data from tasks_queue where pickup_id = '172.31.29.45-1590584573882-2729'
Для извлечения из таблицы tasks_queue используется большее количество java потоков.
Схема таблицы следующая:
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 блокировки индексного разрыва. Вложенный запрос выбора в операторе обновления блокирует просканированные им индексы записей, а также блокирует пробелы в индексах. Я надеюсь, что это поможет кому-то.