MySQL gap lock

Hello, I am god-jiang~

Following the MySQL row lock in the previous article, I shared the lock analysis of various common situations under the RC isolation level. This time I will share the MySQL gap lock, and analyze the lock analysis of various common situations under the RR isolation level.

create table `test`(
  `id` int(11) NOT NULL,
  `a` int(11) NOT NULL,
  `b` int(11) NOT NULL,
  `c` int(11) NOT NULL,
  PRIMARY KEY(`id`),
  UNIQUE KEY unix_key('a'),
  KEY ix_key(`b`)
)ENGINE=InnoDB;

insert into test values(0,0,0,0),(5,5,5,5),(10,10,10,10),(20,20,20,20);

Create a test table, id is the primary key, a is a unique index, b is a normal index, and c is no index.

Now suppose it is in the RC isolation level, let's do an experiment to see:

Transaction A Transaction B
set session transaction_isolation=‘READ-COMMITTED’; set session transation_isolation=‘READ-COMMITTED’;
begin;
select * from test where b=5 for update;
返回:(5,5,5,5)
begin;
insert into test values(6,5,5,5);
commit;
select * from test where b=5 for update;
返回:(5,5,5,5),(6,5,5,5)
commit;

From the above experiment, under the RC isolation level, transaction A adds X lock to the row of b=5, but the b field of a new record inserted by transaction B is also 5, and then b can be found in transaction A =5 There are two records, this produces a "phantom reading".

In other words, the phantom read refers to when the same range is queried twice before and after a transaction, the latter query sees the rows that were not seen in the previous query.

Why is there a phantom reading?

Let's analyze the locking situation of the RC isolation level + b ordinary index at this time:

img

It can be seen that under the RC isolation level, the record of b=5 has X lock, but there is no lock in the gap of (0,5) and (5,10), so new data can be inserted in this gap.

Now I can answer why there is a phantom reading. The reason for the phantom read is that the row lock can only lock the row, but the action of newly inserting a record is to update the "gap" between the records. Therefore, in order to solve the problem of phantom reads, InnoDB introduced a new lock in the RR isolation level, which is the gap lock (Gap Lock).

The above talks about how the phantom reading is generated, and InnoDB introduces the gap lock to solve the phantom reading situation. Next, analyze the lock analysis of the RR isolation level.

Locking analysis (the following default is the RR isolation level and all are currently read)

Here I have selected three common situations under the RC isolation level to analyze how SQL locks:

  • RR isolation level, where field has no index
  • RR isolation level, where field has ordinary index
  • RR isolation level, where field has a unique index

The table structure demonstrated below is the structure at the beginning of the article, and the data is my personal imagination.

RR isolation level + no index

img

As shown in the figure above, the GAP lock is added to the c field (negative infinity, 0), (0, 5), (5, 10), (10, 20), (20, positive infinity). But under the RR isolation level, we all use next-key Lock (row lock + gap lock) by default, so we all default to open left and right closed.

As shown in the figure above, all records have X locks, and GAP locks are also added. Therefore, if this table has not been committed during the execution of select * from test where c=5 for update, any other locked operations will be blocked except for snapshot reads without locks. If this is the case online, it will It would be a very scary thing.

Summary: Under the RR isolation level, the current read of an unindexed condition field will not only add an X lock to each record, but also add a GAP lock. Again, the current read or insert/update/delete operations need to add an index.

RR isolation level + normal index

img

As shown in the figure above, the common index field b=10 adds X locks to two records, and adds X locks to two records of the clustered index tree. GAP locks the range of b (5, 10), (10, 10), (10, positive infinity). Therefore, the next-key Lock locks are (5,10], (10,10], (10, positive infinity). During the period, as long as b is within the range of next-key Lock, all updates will be blocked.

For example: insert into test values(6,6,6,6) will be blocked because the gap lock of the RR isolation level locks the "gap" between records, so the operation will be blocked.

RR isolation level + unique index

The case of the unique index is the simplest, because no matter it is the RC isolation level or the RR isolation level, the unique index can only find one record, and only add X lock to the corresponding row record and it is gone.

Why is this happening?

Because the purpose of the GAP lock is to prevent the same transaction from being read twice in a row, and then the two reads are inconsistent. If the field can be guaranteed to be unique (unique index), in fact, at most only one record can satisfy the condition, so GAP lock will never appear when querying the unique index.

It can be understood that the locking situation of RR+ unique index and RC+ unique index is the same.

to sum up

  • This time, I shared the situation of phantom reading under the RC isolation level, and then analyzed why there is phantom reading.
  • To solve phantom reads, InnoDB introduced GAP locks under RR, which forms next-key Lock with row locks.
  • Analyzed the lock situation of three common situations

Special note: the next-key Lock introduced by InnoDB only solves the phantom read of snapshot reads, but does not solve the phantom read of current reads.

In fact, next-key Lock solves the phantom reading of snapshot reading. A large part of the reason is because of undo log and MVCC. Let me leave a suspense here. I will take the time to write about the sharing of MVCC and share it.

Reference

  • "MySQL 45 Lectures" Lin Xiaobin
  • "Analysis of MySQL Lock Processing" He Dengcheng

Guess you like

Origin blog.csdn.net/weixin_37686415/article/details/115031762