Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this innodb gap lock bug?

enter image description here

trx1 select * from table where refId=4 for update

trx2 insert into table (refId) values (2); block

trx2 will be blocked, i knew trx1 will keep it gap lock, [1,4),[4,7);

my question is why keep gap lock? "insert val 2" is not conflict "select where refId=4 for update", why innodb will keep gap lock, why not use record-lock?

this question has been bothering me for a long time, please tech god save me.

like image 463
Ryan Li Avatar asked Jul 29 '16 10:07

Ryan Li


People also ask

What is InnoDB lock?

InnoDB implements standard row-level locking where there are two types of locks, shared ( S ) locks and exclusive ( X ) locks. A shared ( S ) lock permits the transaction that holds the lock to read a row. An exclusive ( X ) lock permits the transaction that holds the lock to update or delete a row.

Does InnoDB lock on select?

It is important to create good indexes so that your queries do not scan more rows than necessary. InnoDB sets specific types of locks as follows. SELECT ... FROM is a consistent read, reading a snapshot of the database and setting no locks unless the transaction isolation level is set to SERIALIZABLE .


1 Answers

Interesting question.

The gap lock is needed to avoid phantom rows. MySQL works in REPEATABLE-READ isolation level by default. If you run several times select ... for update in your transaction, it should always return same result. Suppose you don't have gap lock and trx2 inserted another row with refId=4 (index is not unique). Then following select in trx1 will return two rows:

MariaDB [test]> select * from t1 where refId=4 for update;
+----+------+
| id | refId|
+----+------+
|  2 |    4 |
|  4 |    4 |
+----+------+
2 rows in set (0.00 sec)

It is not the same result as first select.

like image 185
Pavel Katiushyn Avatar answered Oct 20 '22 17:10

Pavel Katiushyn