Mysql 8.0.x
We stuck on confusing different behevior of SELECT ... LIMIT 1 FOR UPDATE SKIP LOCKED depended on primary index field type.
Let's consider 2 cases of similar tables.
case 1:
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
case 2:
CREATE TABLE `test` (
`id` binary(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
They differ just in field type - INT and BINARY.
Insert 6 items with id 1 to 6.
Run 2 concurent transactions.
Transaction 1:
BEGIN;
SELECT id FROM test
LIMIT 1
FOR UPDATE skip locked;
SELECT SLEEP(10); #for test
COMMIT;
Transaction 2:
BEGIN;
SELECT id
FROM test
WHERE id = 4
FOR UPDATE;
COMMIT;
If id is an INT field select ... for update from transaction 2 executes without waiting of the first transaction commit.
If id is a BINARY filed select ... for update from transaction 2 executes after the second transaction commit
Part of SHOW ENGINE INNODB STATUS output for the second case:
---TRANSACTION 38229, ACTIVE 3 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 12, OS thread handle 6068, query id 1532 localhost 127.0.0.1 root Sending data
SELECT id
FROM test
where id = 4
FOR UPDATE
------- TRX HAS BEEN WAITING 3 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 19 page no 4 n bits 80 index PRIMARY of table `test`.`test` trx id 38229 lock_mode X waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
0: len 11; hex 3100000000000000000000; asc 1 ;;
1: len 6; hex 000000009530; asc 0;;
2: len 7; hex 80000000000000; asc ;;
------------------
---TRANSACTION 38228, ACTIVE 5 sec
2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 8, OS thread handle 12052, query id 1530 localhost 127.0.0.1 root User sleep
SELECT SLEEP(10)
-----------------------------
It was a big surprise...
Could anybody explain why mysql (innodb) behaves so different in these cases.