как innodb блокирует вторичный индекс при обновлении - PullRequest
1 голос
/ 02 мая 2020

Когда я учусь ОБНОВЛЯТЬ запись вторичного индекса, указанную первичным ключом, вторичная блокировка индекса X не может быть показана с помощью show engine innodb status. Тем не менее, когда я пытаюсь заблокировать эту запись вторичного индекса в другом сеансе , она появилась.

Когда UPDATE изменяет запись кластерного индекса, на затронутые записи вторичного индекса принимаются неявные блокировки. Операция UPDATE также принимает общие блокировки для затронутых записей вторичного индекса при выполнении повторных проверок проверки перед вставкой новых записей вторичного индекса и при вставке новых записей вторичного индекса. https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html

информация о таблице

CREATE TABLE `test_lock` (
  `id` int(32) NOT NULL,
  `keyf` int(32) NOT NULL,
  `uniqf` int(32) NOT NULL,
  `nokeyf` int(12) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uniq_b` (`uniqf`),
  KEY `idx_a` (`keyf`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ТЕСТ 1

begin;
update test_lock set keyf=3 where id = 3;
show engine innodb status;

информация о транзакции

только IX и ПЕРВИЧНЫЙ ИНДЕКС X замков можно увидеть.

---TRANSACTION 14987, ACTIVE 5 sec
2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 758, OS thread handle 139959492560640, query id 82046 localhost root
TABLE LOCK table `study`.`test_lock` trx id 14987 lock mode IX
RECORD LOCKS space id 64 page no 3 n bits 80 index PRIMARY of table `study`.`test_lock` trx id 14987 lock_mode X locks rec but not gap
Record lock, heap no 8 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
 0: len 4; hex 80000003; asc     ;;
 1: len 6; hex 000000003a8b; asc     : ;;
 2: len 7; hex 26000001e12bbe; asc &    + ;;
 3: len 4; hex 80000003; asc     ;;
 4: len 4; hex 8000000d; asc     ;;
 5: len 4; hex 80000003; asc     ;;

ТЕСТ 2

блокировка вторичной записи в другом сеансе.

  1. сеанс 1
begin;
update test_lock set keyf=3 where id = 3;
сеанс 2
begin;
select * from test_lock where keyf = 3 for update;
show engine innodb status; мы видим, что появился X LOCK для idx_a. Интересно почему, спасибо.
---TRANSACTION 14992, ACTIVE 20 sec fetching rows
mysql tables in use 1, locked 1
LOCK WAIT 4 lock struct(s), heap size 1136, 3 row lock(s)
MySQL thread id 756, OS thread handle 139959487694592, query id 82052 localhost root Sending data
select * from test_lock where keyf = 3 for update
Trx read view will not see trx with id >= 14992, sees < 14987
------- TRX HAS BEEN WAITING 2 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 64 page no 5 n bits 80 index idx_a of table `study`.`test_lock` trx id 14992 lock_mode X waiting
Record lock, heap no 7 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000003; asc     ;;
 1: len 4; hex 80000003; asc     ;;

------------------
TABLE LOCK table `study`.`test_lock` trx id 14992 lock mode IX
RECORD LOCKS space id 64 page no 5 n bits 80 index idx_a of table `study`.`test_lock` trx id 14992 lock_mode X
Record lock, heap no 2 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000003; asc     ;;
 1: len 4; hex 80000001; asc     ;;

RECORD LOCKS space id 64 page no 3 n bits 80 index PRIMARY of table `study`.`test_lock` trx id 14992 lock_mode X locks rec but not gap
Record lock, heap no 7 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
 0: len 4; hex 80000001; asc     ;;
 1: len 6; hex 0000000039f7; asc     9 ;;
 2: len 7; hex 26000001e12ae3; asc &    * ;;
 3: len 4; hex 80000003; asc     ;;
 4: len 4; hex 80000005; asc     ;;
 5: len 4; hex 80000003; asc     ;;

RECORD LOCKS space id 64 page no 5 n bits 80 index idx_a of table `study`.`test_lock` trx id 14992 lock_mode X waiting
Record lock, heap no 7 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000003; asc     ;;
 1: len 4; hex 80000003; asc     ;;

---TRANSACTION 14987, ACTIVE 394 sec
3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 758, OS thread handle 139959492560640, query id 82046 localhost root
TABLE LOCK table `study`.`test_lock` trx id 14987 lock mode IX
RECORD LOCKS space id 64 page no 3 n bits 80 index PRIMARY of table `study`.`test_lock` trx id 14987 lock_mode X locks rec but not gap
Record lock, heap no 8 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
 0: len 4; hex 80000003; asc     ;;
 1: len 6; hex 000000003a8b; asc     : ;;
 2: len 7; hex 26000001e12bbe; asc &    + ;;
 3: len 4; hex 80000003; asc     ;;
 4: len 4; hex 8000000d; asc     ;;
 5: len 4; hex 80000003; asc     ;;

RECORD LOCKS space id 64 page no 5 n bits 80 index idx_a of table `study`.`test_lock` trx id 14987 lock_mode X locks rec but not gap
Record lock, heap no 7 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 80000003; asc     ;;
 1: len 4; hex 80000003; asc     ;;
...