locking - Mysql select for update blocks 1st insert if using NON primary key in where clause -
mysql version : 5.6.33 , ubuntu 64 bit
table schema
create table `zone_txn` ( `id` bigint(20) not null, `bucket_key` varchar(255) not null, primary key (`id`), index `idx_bucket_key` (`bucket_key`) )
2 sessions opened , race condition induced running 1 statement each terminal. statement numbers mentioned.
terminal 1
s1: begin; s3: select * zone_txn force index(idx_bucket_key) `bucket_key` = 'b1' update; s5: insert zone_txn(`bucket_key`) values('b1'); s7: commit;
terminal 2
s2: begin; s4: select * zone_txn force index(idx_bucket_key) `bucket_key` = 'b2' update; s6: insert zone_txn(`bucket_key`) values('b2'); s8: commit;
according doc , select update "only locks rows has passed through update".
question : insert query blocked in whichever session receives first insert query. insert query after blocked query ( in second session ) works fine. in above example s5 blocks, s6 runs fine.
is dues gap lock or next-key lock specified here fresh insert being blocked index.
if put id
= <> in clause , both insert queries run fine.
terminal 1
s1: begin; s3: select * zone_txn `id` = 1 update; s5: insert zone_txn(`bucket_key`) values('b1'); s7: commit;
terminal 2
s2: begin; s4: select * zone_txn `id` = 2 update; s6: insert zone_txn(`bucket_key`) values('b2'); s8: commit;
updated: if make bucket_key unique index , works fine. looks works unique , primary keys , not ranges.
updated : fixed typo, added "for update" in select statements part of question.
updated : starting value of zone_txn;
+----+------------+ | id | bucket_key | +----+------------+ | 1 | b1 | | 2 | b2 | +----+------------+
show engine innodb status;
---transaction 1139415, active 11 sec 4 lock struct(s), heap size 1184, 4 row lock(s), undo log entries 1 mysql thread id 8818, os thread handle 0x700009268000, query id 1700769 localhost root cleaning ---transaction 1139414, active 16 sec inserting mysql tables in use 1, locked 1 lock wait 5 lock struct(s), heap size 1184, 4 row lock(s), undo log entries 1 mysql thread id 8626, os thread handle 0x7000092f0000, query id 1700768 localhost root update insert zone_txn(`bucket_key`) values('b1') ------- trx has been waiting 6 sec lock granted: record locks space id 1454 page no 4 n bits 72 index `idx_bucket_key` of table `kyc`.`zone_txn` trx id 1139414 lock_mode x locks gap before rec insert intention waiting record lock, heap no 3 physical record: n_fields 2; compact format; info bits 0 0: len 2; hex 6232; asc b2;; 1: len 8; hex 8000000000000002; asc ;;
Comments
Post a Comment