Why MySQL InnoDB update also set gap lock?

Jacky1205 :

As far as I know the gap lock is used to prevent phantom read, and I found gap lock is set by locking read in most articles via Google search.

A gap lock is a lock on a gap between index records, or a lock on the gap before the first or after the last index record. For example, SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE; prevents other transactions from inserting a value of 15 into column t.c1, whether or not there was already any such value in the column, because the gaps between all existing values in the range are locked.

https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html#innodb-gap-locks

I guess this (set gap lock on locking read) is sufficient. Why update, delete also set gap lock.

UPDATE ... WHERE ... sets an exclusive next-key lock on every record the search encounters. However, only an index record lock is required for statements that lock rows using a unique index to search for a unique row.

https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html

And another issue is what happened if there is no suitable index where gap lock can be attached? Does fall back to lock on the entire table?

Here we assumed that using the default transaction isolation level Repeatable Read.

Bill Karwin :

It depends on the conditions in your SELECT, UPDATE, or DELETE. They set gap locks to prevent other concurrent sessions from adding rows to the set that would be matched by the conditions.

In InnoDB, locking statements always lock the most recent committed row versions. So they don't really obey the REPEATABLE READ snapshot. They act more like READ-COMMITTED.

Therefore, if you do a statement like this:

UPDATE FROM MyTable SET ... WHERE created_at > '2020-03-22';

It must lock the gap following the highest value of created_at, which will prevent other sessions from adding new rows.

This is to simulate REPEATABLE READ, to make sure that if you run the same UPDATE again, it will affect the same rows, and it won't accidentally affect new rows.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=371898&siteId=1