Recently I read InnoDB Locks in MySQL5.7 doc, https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html#innodb-gap-locks. I'm confuse about Next-Key Lock and Gap Lock. In the doc, the Next-Key Lock locks the record and the gap before it, and the Gap Lock locks the only the gap? for example:
CREATE TABLE `r` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`k` int(11) DEFAULT NULL,
`u` int(11) DEFAULT NULL,
`v` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_u` (`u`),
KEY `idx_k` (`k`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8
insert into r values (2,2,2,2),(6,6,6,6),(7,7,7,7);
statement 1:
select * from r where u = 4 for update;
statement 1 use the unique index search the record dose not exist, it use the gap lock, lock the area u B+tree from (u=2, id=2) to (u=6, id=6) prevent from inserting, but do not lock the record k B+tree (u=2, id=2) and (u=6, id=6).
statement 2:
select * from r where k = 6 for update;
statement 2 use the non-unique index search the record existed, it use the next-key lock locks the area k B+tree from ((k=2, id=2), (k=6, id=6)] and a gap lock locks the area k B+tree from ((k=6, id=6), (k=7, id=7)) ,also lock the cluster-index where id = 6;
so my question is:
1, the lock area ((k=2, id=2), (k=6, id=6)] is a next-key lock, and the area ((k=6, id=6), (k=7, id=7)) is a gap lock, am I right?
2,Is the understanding of the two statement right?
Please forgive me for my English.
A MySQL Locks is nothing but a flag that can be assigned to a table to alter its properties. MySQL allows a table lock that can be assigned by a client-server to prevent other sessions from being able to access the same table during a specific time frame.
MySQL uses table-level locking for all storage engines except InnoDB meaning that table-level locking is used for tables running the MyISAM, MEMORY and MERGE storage engines, permitting only one session to update tables at a time.
Pessimistic concurrency control: when a transaction is modifying data, pessimistic locking applies a lock to the data so other transactions can't access the same data. After the transaction commits, the lock is released.
A SELECT ... FOR UPDATE reads the latest available data, setting exclusive locks on each row it reads. Thus, it sets the same locks a searched SQL UPDATE would set on the rows.
I think all your statements are right.
Another way to check the answer is to check the data_locks table for the locks performed by innodb.
select * from performance_schema.data_locks;
And you can check the LockMode column:
X/S, Gap :the combo means gap lock end;
X/S, Rec_not_gap :the combo means record lock.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With