Core interview questions: MVCC, gap locks, Undo Log chains, table-level locks, row-level locks, page-level locks, shared locks, exclusive locks, record locks, etc.

Foreword:

In Nien's reader community (50+), we often encounter: MVCC, gap locks, Undo Log chains, table-level locks, row-level locks, page-level locks, shared locks, exclusive locks, record locks, etc. related interview questions.

Here, Nien will give you a systematic and systematic sorting out, so that you can fully demonstrate your strong "technical muscles", and make the interviewer love "can't help yourself, salivate".

Also include this question and the reference answer in our " Nin Java Interview Collection PDF ", for the reference of the following friends, to improve everyone's 3-high architecture, design, and development level.

Note: This article is continuously updated in PDF. For the latest PDF files of Nien’s architecture notes and interview questions, please get them from the link below: Code Cloud

Chat: How does the MVCC mechanism solve phantom reading?

Under the isolation level of RR, Innodb uses MVCC and next-key locks (a combination of row locks and gap locks) to solve phantom reading,

  • MVCC solves the phantom reading of ordinary reading (snapshot reading ),
  • next-key locks solve the phantom reading in the current reading situation.

So, let's take a look at how the MVCC mechanism is a phantom read for ordinary reads (snapshot reads )?

After understanding these concepts, let's see how the system finds it through MVCC when querying a record:

  1. First obtain the version number of the transaction itself, that is, the transaction ID;
  2. Get the ReadView view;
  3. Query the obtained data, and then compare it with the transaction version number in ReadView;
  4. If the ReadView rule is not met, a historical snapshot needs to be obtained from the Undo Log;
  5. Finally, return the data that conforms to the rules.

Different isolation levels, or different numbers of Read Views:

  • When the isolation level is RC Read Committed, each SELECT query in a transaction will reacquire the Read View. As shown in the table:

Note that at this time, the same query statement will obtain the Read View again. If the Read View is different at this time, non-repeatable reads or phantom reads may occur.

  • When the isolation level is RR repeatable read, non-repeatable read is avoided. This is because a transaction will only obtain a Read View once in the first SELECT, and all subsequent SELECTs will reuse this Read View, as follows As shown in the table:

Example: Under the READ COMMITTED isolation level

READ COMMITTED : Generate a ReadView every time before reading data.

Now there are two transactions with transaction ids 10 and 20 being executed:

# Transaction 10 BEGIN;
UPDATE student SET name="李四" WHERE id=1; 
UPDATE student SET name="王五" WHERE id=1; 

# Transaction 20 BEGIN; 
# 更新了一些别的表的记录 ...

At this moment, the version linked list obtained by the record whose id is 1 in the table student is as follows:

illustrate:

During transaction execution, only when the record is actually modified for the first time (such as using INSERT, DELETE, UPDATE statements), a separate transaction id will be assigned, and this transaction id is incremented. Place

So we update some records of other tables in transaction 2, the purpose is to let it assign a transaction id.

Assuming that a transaction using the READ COMMITTED isolation level is now executed:

# 使用READ COMMITTED隔离级别的事务 
BEGIN;
# SELECT1:Transaction 10、20未提交

SELECT * FROM student WHERE id = 1; # 得到的列name的值为'张三'

After that, we submit the transaction with transaction id 10:

# Transaction 10 
BEGIN; UPDATE student SET name="李四" WHERE id=1; 
UPDATE student SET name="王五" WHERE id=1;
COMMIT;

Then go to the transaction with transaction id 20 to update the record with id 1 in the table student:

# Transaction 20
BEGIN; # 更新了一些别的表的记录 ... 
UPDATE student SET name="钱七" WHERE id=1; 
UPDATE student SET name="宋八" WHERE id=1;

At this moment, the version chain of the record whose id is 1 in the table student looks like this:

Then go to the transaction that used the READ COMMITTED isolation level just now, and continue to find the record with id 1, as follows:

# 使用READ COMMITTED隔离级别的事务 
BEGIN;

# SELECT1:Transaction 10、20均未提交
SELECT * FROM student WHERE id = 1;

# 得到的列name的值为'张三'
# SELECT2:Transaction 10提交,Transaction 20未提交 

SELECT * FROM student WHERE id = 1; 
# 得到的列name的值为'王五'

The execution process of this SELECT2 is as follows:

Step 1 : When the SELECT statement is executed, a ReadView will be generated separately. The content of the trx_ids list of the ReadView is [20], the up_limit_id is 20, the low_limit_id is 21, and the creator_trx_id is 0.

Step 2 : Select the visible records from the version chain. It can be seen from the figure that the content of the column name of the latest version is 'Song Ba', and the tr×_id value of this version is 20, which is in the trx_ids list, so it does not conform to the visible Sexual requirements, skip to the next version according to roll.pointer.

Step 3 : The content of the column name in the next version is 'Qianqi', and the trx_id value of this version is 20, which is also in the trx_ids list, so it does not meet the requirements, continue to skip to the next version.

Step 4 : The content of the column name in the next version is 'Wang Wu', and the trx_id value of this version is 10, which is smaller than the up_limit.id value of 20 in ReadView, so this version meets the requirements, and the final version returned to the user is This column name is the record of 'Wang Wu'.

By analogy, if the record with the transaction id of 20 is also submitted later, when the record with the id value of 1 in the student table is queried again in the transaction using the READ CONMMITTED isolation level, the result is 'Song Ba'. The specific process We will not analyze it.

Under the REPEATABLE READ isolation level

For transactions using the REPEATABLE READ isolation level, a ReadView will only be generated when the query statement is executed for the first time, and subsequent queries will not be generated repeatedly.

For example, there are two transactions with transaction ids 10 and 20 in the system being executed:

# Transaction 10 
BEGIN;
UPDATE student SET name="李四" WHERE id=1; 
UPDATE student SET name="王五" WHERE id=1;

# Transaction 20 BEGIN; # 更新了一些别的表的记录 ...

At this moment, the version linked list obtained by the record whose id is 1 in the table student is as follows:

Assuming that a transaction using the REPEATABLE READ isolation level is now executed:

# 使用REPEATABLE READ隔离级别的事务 
BEGIN;
# SELECT1:Transaction 10、20未提交
SELECT * FROM student WHERE id = 1; # 得到的列name的值为'张三'

After that, we submit the transaction with transaction id 10, like this:

# Transaction 10
BEGIN; 
UPDATE student SET name="李四" WHERE id=1;
UPDATE student SET name="王五" WHERE id=1;

COMMIT;

Then go to the transaction with transaction id 20 to update the record with id 1 in the table student:

# Transaction 20 
BEGIN;

# 更新了一些别的表的记录 ... 
UPDATE student SET name="钱七" WHERE id=1;  
UPDATE student SET name="宋八" WHERE id=1;

At this moment, the version chain length of the record whose id is 1 in the table student is as follows:

Then go to the transaction that just used the REPEATABLE READ isolation level to continue to look for the record with id 1, as follows:

# 使用REPEATABLE READ隔离级别的事务 

BEGIN; 
# SELECT1:Transaction 10、20均未提交
SELECT * FROM student WHERE id = 1; # 得到的列name的值为'张三'

# SELECT2:Transaction 10提交,Transaction 20未提交 
SELECT * FROM student WHERE id = 1;  # 得到的列name的值仍为'张三'

The execution process of this SELECT2 is as follows:

Step 1 : Because the isolation level of the current transaction is REPEATABLE READ, and ReadView has been generated when SELECT1 is executed before, so the previous ReadView is directly reused at this time, and the content of the trx_ids list of the previous ReadView is [10, 20]. up_limit_id is 10, low_limit_id is 21, creator_trx_id is 0.

Step 2 : Then select the visible records from the version chain. It can be seen from the figure that the content of the column name of the latest version is 'Song Ba' with a trx_id value of 20, which is in the trx_ids list, so it does not meet the visibility requirements. According to roll_pointer skips to the next version.

Step 3 : The content of the column name of the next version is 'Qianqi', the trx_id value of this version is 20, which also meets the requirements in the trx_ids list, continue to skip to the next version.

Step 4 : The content of the column name in the next version is 'Wang Wu', the trx_id value of this version is 10, and the trx_ids list contains the transaction id with a value of 10, so this version does not meet the requirements, the same reason The content of a column name is the version of 'Li Si' also does not meet the requirements. Keep skipping to the next version.

Step 5 : The content of the column name in the next version is 'Zhang San', the trx_id value of this version is 80, which is smaller than the up_limit_id value of 10 in Readview, so this version meets the requirements, and the final version returned to the user is this Column c is the record of 'Zhang San'.

The results of the two SELECT queries are duplicated, and the value of column c of the record is 'Zhang San', which is the meaning of repeatable reading.

If we submit the record with the transaction id of 20 later, and then continue to search for the record with the id of 1 in the transaction that just used the REPEATABLE READ isolation level refresh, the result is still 'Zhang San'. You can refer to the specific execution process Analyze it yourself.

How to solve phantom reading

Next, explain how InnoDB solves phantom reading.

Assuming that there is only one piece of data in the student table, in the data content, the primary key id=1, and the hidden trx_id=10, its undo log is shown in the figure below.

Assume that transaction A and transaction B are executed concurrently, the transaction id of transaction A is 20, and the transaction id of transaction B is 30.

Step 1 : Transaction A starts to query data for the first time, and the query SQL statement is as follows.

select * from student where id >= 1;

Before starting the query, MySQL will generate a ReadView for transaction A. At this time, the content of ReadView is as follows: trx_ids= [20,30] , up_limit_id=20 , low_limit_id=31 , creator_trx_id=20 .

Since there is only one piece of data in the table student at this time, and it meets the condition of where id>=1, it will be queried.

Then according to the ReadView mechanism, it is found that the trx_id=10 of the data in this row is smaller than the up_limit_id in the ReadView of transaction A, which means that this data is submitted by other transactions before transaction A starts, so transaction A can read it.

Conclusion: The first query of transaction A can read a piece of data with id=1.

Step 2 : Following transaction B (trx_id=30), insert two new pieces of data into the student table, and submit the transaction.

insert into student(id,name) values(2,'李四'); insert into student(id,name) values(3,'王五');

At this time, there are three pieces of data in the student table, and the corresponding undo is shown in the figure below:

Step 3 : Then transaction A starts the second query. According to the rules of the repeatable read isolation level, transaction A will not regenerate ReadView at this time. At this time, the three pieces of data in the table student all meet the condition of where id>=1, so they will be checked out first. Then, according to the ReadView mechanism, it is judged whether each piece of data can be seen by transaction A.

1) First of all, the data with id=1, as mentioned earlier, can be seen by transaction A.

2) Then there is the data with id=2, and its trx_id=30. At this time, transaction A finds that this value is between up_limit_id and low_limit_id, so it needs to judge whether 30 is in the trx_ids array. Since transaction A's trx_ids=[20,30], in the array, this means that the data with id=2 was submitted by other transactions started at the same time as transaction A, so this data cannot be seen by transaction A .

3) Similarly, for the piece of data with id=3, trx_id is also 30, so it cannot be seen by transaction A.

Conclusion: The second query of the final transaction A can only query the data with id=1. This is the same as the result of the first query of transaction A, so there is no phantom reading phenomenon, so under the repeatable read isolation level of MySQL, there is no phantom reading problem .

Summarize

Here is an introduction to the process of MVCC accessing the recorded version chain when transactions at the two isolation levels of READ COMMITTD and REPEATABLE READ execute snapshot read operations. In this way, the read-write and write-read operations of different transactions are executed concurrently, thereby improving system performance.

The core point is the principle of ReadView. A big difference between the two isolation levels of READ COMMITTD and REPEATABLE READ is the timing of generating ReadView:

READ COMMITTD generates a ReadView before every normal SELECT operation

REPEATABLE READ only generates a ReadView before the first normal SELECT operation, and then reuse this ReadView for subsequent query operations.

Through MVCC we can solve:

1. The problem of blocking between reading and writing.

Through MVcc, reading and writing can not block each other, that is, reading does not block writing, and writing does not block reading, so that concurrent transaction processing capabilities can be improved.

2. Reduced the probability of deadlock.

This is because MVCC adopts an optimistic locking method, which does not require locking when reading data, and only locks necessary rows for writing operations.

3. Solve the problem of snapshot reading.

When we query the snapshot of the database at a certain point in time, we can only see the update results submitted by transactions before this point in time, but not the update results submitted by transactions after this point in time.

Chat: MySQL gap lock, how to solve phantom reading?

Under the isolation level of RR, Innodb uses MVCC and next-key locks (a combination of row locks and gap locks) to solve phantom reading,

  • MVCC solves the phantom reading of **normal read (snapshot read)**,
  • next-key locks solve the phantom reading in the current reading situation.

MySQL gap lock + record lock, combined, solves the phantom reading in the current reading situation

gap lock

InnoDB supports three locking methods:

  • Record Lock (Record Lock): The lock is directly added to the index record.
  • Gap Lock: The lock is added to the free space that does not exist, which can be between two index records, or the space before the first index record or after the last index.
  • Next-Key Lock: The combination of record lock and gap lock is called Next-Key Lock.

Gap lock: When we use range conditions instead of equality conditions to retrieve data and request shared or exclusive locks, InnoDB will lock the index items of existing data records that meet the conditions; for key values ​​that are within the condition range but do not exist The record, called "Gap (GAP)",

InnoDB will also lock this "gap". This locking mechanism is the so-called gap lock (Gap Lock lock).

For example, if there are only 101 records in the user table, and the empid values ​​are 1, 2, ..., 100, 101, the following SQL:

select * from  user where user_id > 100 for update;

It is a retrieval of range conditions. InnoDB will not only lock the records with user_id value of 101 that meet the condition, but also lock the "gap" with user_id greater than 101 (these records do not exist).

The reason for phantom reading is that row locks can only lock rows, but the action of newly inserting records needs to update the "gap" between records.

Therefore, in order to solve the problem of phantom reading, InnoDB had to introduce a new lock, that is, a gap lock (Gap Lock).

The purpose of InnoDB's use of gap locks is to prevent phantom reading on the one hand and to meet the requirements of the relevant isolation level.

For the above example, if the gap lock is not used, if other transactions insert any records with user_id greater than 100, then if the transaction executes the above statement again, phantom reading will occur;

On the other hand, it is to meet the needs of its recovery and replication.

Snapshot read and current read

Snapshot read (historical data) - mvcc

InnoDB's default transaction isolation level is rr (repeatable read). Its implementation technology is mvcc (MVCC only works under the two isolation levels of read committed and repeatable read).

Version-based control protocol. This technology can not only guarantee repeatable reading of InnoDB, but also prevent phantom reading.

But what it prevents is snapshot reading, that is, although the read data is consistent, the data is historical data.

SQL syntax corresponding to snapshot reading: simple select operation (excluding select ... lock in share mode, select ... for update)

Current read (latest data) - next-key lock

How to ensure that the data is consistent (that is, when a transaction reads a certain data internally, the data is the same), and the data read at the same time is the latest data.

InnoDB provides next-key lock, which is to combine gap lock and row lock to achieve the ultimate goal.

The sql syntax corresponding to the current read (latest data):

select * from table where ? lock in share mode;
select * from table where ? for update;
insert into table values ();
update table set ? where ?;
delete from table where ?;

Special read operations, insert/update/delete operations, belong to the current read and need to be locked.

In short:

At the RR level, snapshot reading is implemented through MVCC (multi-version control) and undo log, and current reading is implemented by adding record lock (record lock) and gap lock (gap lock).

Chat: What are table-level locks, row-level locks, and page-level locks?

Simply put, the database locking mechanism is a rule designed by the database to ensure data consistency and make various shared resources orderly when accessed concurrently .

Due to the characteristics of its own architecture, the MySQL database has multiple data storage engines. The locking mechanism of each storage engine is optimized for the specific scenarios they face, so the locking mechanisms of each storage engine are also quite different.

Each MySQL storage engine uses three types (levels) of locking mechanisms: 表级锁定, 行级锁定and 页级锁定.

1. Table-level lock

Table-level locking is the most granular locking mechanism among MySQL storage engines. The biggest feature of this locking mechanism is that the implementation logic is very simple, and the negative impact on the system is minimal. So the speed of acquiring and releasing locks is very fast.

Of course, the biggest negative impact of large locking granularity is that the probability of lock resource contention will be the highest, resulting in a greatly reduced concurrency .

Some non-transactional storage engines such as MyISAM, MEMORY, and CSV mainly use table-level locking.

2. Row-level locks

The biggest feature of row-level locking is that the granularity of locked objects is very small . Because of the small granularity of locking, the probability of contention for locking resources is also the smallest. It can give applications as much concurrent processing capability as possible and improve some applications that require high concurrency. Overall performance of the application system.

Although it has great advantages in concurrent processing capabilities, row-level locking also brings many disadvantages.

Since the granularity of locking resources is very small, more things need to be done each time the lock is acquired and released, and the consumption is naturally greater. In addition, row-level locking is also the most prone to deadlocks .

使用行级锁定的主要是InnoDB存储引擎

3. Page-level lock

Page-level locking is a unique locking level in MySQL.

The feature of page-level locking is that the locking granularity is between row-level locking and table-level locking, so the resource overhead required to acquire locking and the concurrent processing capabilities it can provide are also between the above two.

The main one that uses page-level locking is the BerkeleyDB storage engine.

4. Summary

In general, the characteristics of the three MySQL locks can be roughly summarized as follows:

表级锁: Small overhead, fast locking; no deadlock; large locking granularity, the highest probability of lock conflicts, and the lowest concurrency;

行级锁: The overhead is high, and locking is slow; deadlocks will occur; the locking granularity is the smallest, the probability of lock conflicts is the lowest, and the concurrency is the highest;

页面锁: The overhead and locking time are between table locks and row locks; deadlocks will occur; the locking granularity is between table locks and row locks, and the concurrency is average.

Chat: What are shared locks and exclusive locks?

InnoDB implements standard row-level locks , including two types:

  • Shared lock (referred to as s lock),
  • Exclusive lock (referred to as x lock).

For shared locks, adding a shared lock to the current row will not block other transactions' read requests for the same row, but will block write requests for the same row.

Only after the read lock is released, the write operation of other things will be performed.

For an exclusive lock, it will block the read and write operations of other transactions on the same row, and only when the write lock is released, will the read and write operations of other transactions be performed.

In short, it is:

  • Read locks block writes (X), but not reads (S)
  • The write lock will block both the read (S) and write (X)

For InnoDB in RR (MySQL default isolation level), for update, delete and insert statements, an exclusive lock (X) will be automatically added to the data set involved;

For ordinary select statements, innodb will not add any locks.

If you want to add an S lock or an X lock during the select operation, we need to add the lock manually.

-- 加共享锁(S)
select * from table_name where ... lock in share mode

-- 加排它锁(X)
select * from table_name where ... for update

When reading, use select... in share mode to obtain a shared lock,

It is mainly used to confirm whether a row of records exists when data dependencies are required, and to ensure that no one updates or deletes this record.

When reading, use select... for update to obtain an exclusive lock

However, if the current transaction also needs to update the record, it may cause deadlock. For applications that need to update the row after locking the record, you should use the select... for update method to obtain an exclusive lock.

Let's talk: What are Record Locks?

Record locks are actually easy to understand. Locking records in a table is called a record lock, or row lock for short.

for example

SELECT * FROM `test` WHERE `id`=1 FOR UPDATE;

It will add a record lock on the record with id=1 to prevent other transactions from inserting, updating, and deleting the row with id=1.

have to be aware of is:

  • The id column must be a unique index column or a primary key column, otherwise the lock added by the above statement will become a key lock (the key lock will be discussed below).
  • At the same time, the query statement must be an exact match (=), not >, <, like, etc. , otherwise it will degenerate into a temporary key lock.

other implementations

When the UPDATE operation is performed on the data row through the primary key index and the unique index , the row data will also be locked:

-- id 列为主键列或唯一索引列 
UPDATE SET age = 50 WHERE id = 1;

The record lock is to lock the record, lock the index record, not the real data record .

If the column to be locked has no index, perform full table record lock

The record lock is also an exclusive (X) lock, so it will block other transactions from inserting, updating, and deleting it .

Let's talk: What are Gap Locks?

Gap lock is a lock mechanism introduced by Innodb under the RR (repeatable read) isolation level to solve the phantom read problem.

Gap lock is a kind of row lock in InnoDB .

Please keep in mind: what is locked by gap lock is an interval, not just every piece of data in this interval .

For example, if there are only 101 records in the emp table, and the empid values ​​are 1, 2, ..., 100, 101, the following SQL:

SELECT * FROM emp WHERE empid > 100 FOR UPDATE

When we use conditions to retrieve data and request shared or exclusive locks, InnoDB will not only lock the records with an empid value of 101 that meet the conditions, but also lock the "gap" with an empid greater than 101 (these records do not exist) .

At this time, if you insert data with empid equal to 102, if the transaction has not been submitted, then you will be in a waiting state and cannot insert data.

There are still quite a lot to say about gap locks. I will write a separate article to analyze gap locks and attach a complete example to the article.

Let's talk: What are Next-Key Locks?

Next-key lock is a combination of record lock and gap lock, which refers to the lock added to a record and the gap in front of this record.

It can also be understood as a special gap lock .

The problem of phantom reading can be solved by temporarily building locks .

There will be a temporary key lock on the non-unique index column on each data row . When a transaction holds the temporary key lock of the data row , it will lock a section of data in the left-open and right-close interval .

It should be emphasized that row- are implemented based on indexes.

临键锁只与 非唯一索引列 有关,在 唯一索引列(包括主键列)上不存在临键锁。

Suppose you have the following table:

id primary key, age common index

The potential key locks for the age column in this table are:
(-∞, 10],
(10, 24],
(24, 32],
(32, 45],
(45, +∞],

Execute the following command in transaction A:

-- 根据非唯一索引列 UPDATE 某条记录 
UPDATE table SET name = Vladimir WHERE age = 24; 
-- 或根据非唯一索引列 锁住某条记录 
SELECT * FROM table WHERE age = 24 FOR UPDATE; 

No matter which sentence in the above SQL is executed, if the following command is executed in transaction B later, the command will be blocked:

INSERT INTO table VALUES(100, 26, 'tianqi'); 

Obviously, while transaction A performs UPDATE operation on the column whose age is 24, it also acquires the temporary key lock in the interval (24, 32].

Here is a summary of record locks , gap locks , and key locks

  • The implementation of row locks in InnoDB depends on the index , and once a locking operation does not use the index, the lock will degenerate to 表锁.
  • Record locks exist in unique indexes , including primary key indexes , and lock a single index record.
  • Gap locks exist in non-unique indexes and lock an interval within the range of an open range .
  • Adjacent key locks exist in non-unique indexes . This type of lock exists on the index of each record of this type. It is a special gap lock that locks an index interval that is opened on the left and closed on the right .

Chat: What is an intent lock?

Intention locks are divided into 意向共享锁(IS)and意向排他锁(IX)

  • Intentional shared (IS) lock : the transaction intends to add shared locks (S locks) to certain rows in the table
-- 事务要获取某些行的 S 锁,必须先获得表的 IS 锁。 
SELECT column FROM table ... LOCK IN SHARE MODE;
  • Intentional exclusive (IX) lock : The transaction intends to add an exclusive lock (X lock) to certain rows in the table
 -- 事务要获取某些行的 X 锁,必须先获得表的 IX 锁。
 SELECT column FROM table ... FOR UPDATE;

First of all, we need to understand four points

  • Both intent shared locks (IS) and intent exclusive locks (IX) are table locks .
  • It is very important that intent locks are table-level locks that do not conflict with row-level locks.
  • Intention locks are automatically added by InnoDB without user intervention.
  • Intention locks are internal locks that exist under InnoDB. For MyISAM, there is no such thing as intention locks.

There will be doubts here, since there are already shared locks (S locks) and exclusive locks (X locks) before.

So why do you need to introduce intent locks? What problem can it solve?

We can understand that the purpose of the intent lock is to let InnoDB 中的行锁和表锁更高效的共存.

Why do you say that, let's give an example.

example

Below is a table InnoDB RR isolation level id is the primary key

Transaction A acquires an exclusive lock on a row and does not commit:

SELECT * FROM users WHERE id = 6 FOR UPDATE; 

Transaction B wants to acquire a table lock on the users table :

LOCK TABLES users READ; 

Because shared locks and exclusive locks are mutually exclusive, transaction B must ensure that:

  • No other transactions currently hold exclusive locks on the users table.
  • No other transaction currently holds an exclusive lock on any row in the users table.

In order to check whether the second condition is met, transaction B must check whether there is an exclusive lock on each row in the table under the premise of ensuring that there is no exclusive lock on the users table . Obviously this is a very inefficient approach, but with the intent lock , the situation is different: transaction B only needs to check whether there is

Intention shared locks, if there are some rows in the table are locked by shared row locks , therefore, the write lock applied by transaction B for the table will be blocked. Wouldn't that be more efficient?

This also explains why it should be clear why intentional locks exist.

We can give an example in life to understand why there is an intention lock.

For example, it’s like a playground where many children go in to play. If the janitor wants to lock the playground door after work ( with a watch lock ), he must check every corner to ensure that every child is safe. The door can be locked only after leaving ( releasing the row lock ).

Assuming that locking the door is a frequent occurrence, the uncle will be very broken. The uncle thought of a way. Every child enters and writes his name on the notebook. When the child leaves, he crosses out his name. Then the uncle can easily know whether there are children in the playground without having to Search every corner.

The "small book" in the example is the intent lock . The information he records is not detailed. He just reminds the uncle that someone is in the house.

Here we look at the compatibility of shared (S) locks, exclusive (X) locks, intention shared locks (IS), and intention exclusive locks (IX)

It can be seen that the intent locks are compatible with each other . So what is the meaning of your existence?

Intention locks will not embarrass intent locks. It will not embarrass row-level exclusive (X)/shared (X) locks, its existence is embarrassing 表级exclusive (X)/shared (X) locks.

注意The exclusive (X)/shared (S) locks here refer to table locks! Intention locks are not mutually exclusive with row-level shared/exclusive locks! The row-level X and S can follow the above compatibility rules.

Intention locks are always compatible with intent locks, because when you add row-level X locks or S locks, you will automatically acquire table-level IX locks or IS locks. That is, if you have 10 transactions, and row-level X locks are added to 10 different rows, then there are 10 IX locks at this time.

What is the purpose of the existence of 10IX? If there is a transaction at this time and you want to add an exclusive X lock to the entire table, then it does not need to traverse each row to see if there is an S or X lock, but to see if there is an intention lock. As long as there is an intent lock, the transaction cannot add a table-level exclusive X lock until all the above 10 IXs are released.

Let's talk: What is an insertion intent lock?

Before explaining the insertion of intention locks, let's think about a question

Below is a table id primary key, age common index

First, transaction A inserts a row of data, and there is no commit :

INSERT INTO users SELECT 4, 'Bill', 15; 

Then transaction B tries to insert a row of data:

INSERT INTO users SELECT 5, 'Louis', 16; 

Excuse me:

1. What lock does transaction A use?

2. Will transaction B be blocked by transaction A ?

The insertion intention lock is a kind of one generated by the INSERT operation before inserting a row 间隙锁.

This lock is used to indicate the insertion intention . When multiple transactions insert multiple pieces of data with different positions in the same interval (gap) , the transactions do not need to wait for each other .

Assume that there are two records with values ​​4 and 7, and two different transactions try to insert two records with values ​​5 and 6 respectively. Each transaction will acquire ( 4, 7) between the gap lock , but because the data rows do not conflict, so between the two transactions

There will be no conflict (blocking wait).

In summary, the characteristics of inserting intent locks can be divided into two parts:

  • The insertion intention lock is a special kind of gap lock - the gap lock can lock some records in the open range .
  • The insertion intention locks are not mutually exclusive, so even if multiple transactions insert multiple records in the same interval, as long as the records themselves ( primary key , unique index ) do not conflict, there will be no conflict waiting between transactions .

It needs to be emphasized that although the insertion intention lock contains the word intention lock , it does not belong to the intention lock but the gap lock , because the intention lock is a table lock插入意向锁是行锁 .

Now we can answer the opening question:

1. Use insert intent locks and record locks .

2. Transaction A will not block transaction B.

Why not use gap lock

What if you just use ordinary gap locks ?

We are looking at transaction A, in fact, it has acquired a total of 3 locks

  • A record lock for the record row with id 4 .
  • The age interval is in (10, 15) gap lock .
  • The age interval is in (15, 20) gap lock .

In the end, transaction A inserted the row of data and locked the range (10, 20).

Then transaction B tries to insert a row of data:

INSERT INTO users SELECT 5, 'Louis', 16; 

Because 16 is located in the (15, 20) interval, and there is a gap lock in this interval , so transaction B doesn't even want to apply for its own gap lock , it can't even acquire the record lock of this row , so it can only obediently Wait for transaction A to end before performing the insert operation.

Obviously, in this way, transactions will frequently fall into blocking waiting , and the concurrency of insertion is very poor.

At this time, if we think back to the insertion intention lock we just talked about , it is not difficult to find how it elegantly solves the problem of concurrent insertion .

Summarize

  • Under the transaction isolation level of RR, InnoDB uses insert intent locks to control and resolve concurrent inserts.
  • An insertion intent lock is a special kind of gap lock.
  • Insert intent locks are not mutually exclusive when the locking range is the same but the record rows themselves do not conflict.

Note: This article is continuously updated in PDF. For the latest PDF files of Nien’s architecture notes and interview questions, please get them from the link below: Code Cloud

The realization path of technical freedom:

Realize your architectural freedom:

" Have a thorough understanding of the 8-figure-1 template, everyone can do the architecture "

" 10Wqps review platform, how to structure it? This is what station B does! ! ! "

" Alibaba Two Sides: How to optimize the performance of tens of millions and billions of data?" Textbook-level answers are coming "

" Peak 21WQps, 100 million DAU, how is the small game "Sheep a Sheep" structured? "

" How to Scheduling 10 Billion-Level Orders, Come to a Big Factory's Superb Solution "

" Two Big Factory 10 Billion-Level Red Envelope Architecture Scheme "

… more architecture articles, being added

Realize your responsive freedom:

" Responsive Bible: 10W Words, Realize Spring Responsive Programming Freedom "

This is the old version of " Flux, Mono, Reactor Combat (the most complete in history) "

Realize your spring cloud freedom:

" Spring Cloud Alibaba Study Bible " PDF

" Sharding-JDBC underlying principle and core practice (the most complete in history) "

" Get it done in one article: the chaotic relationship between SpringBoot, SLF4j, Log4j, Logback, and Netty (the most complete in history) "

Realize your linux freedom:

" Linux Commands Encyclopedia: 2W More Words, One Time to Realize Linux Freedom "

Realize your online freedom:

" Detailed explanation of TCP protocol (the most complete in history) "

" Three Network Tables: ARP Table, MAC Table, Routing Table, Realize Your Network Freedom!" ! "

Realize your distributed lock freedom:

" Redis Distributed Lock (Illustration - Second Understanding - The Most Complete in History) "

" Zookeeper Distributed Lock - Diagram - Second Understanding "

Realize your king component freedom:

" King of the Queue: Disruptor Principles, Architecture, and Source Code Penetration "

" The King of Cache: Caffeine Source Code, Architecture, and Principles (the most complete in history, 10W super long text) "

" The King of Cache: The Use of Caffeine (The Most Complete in History) "

" Java Agent probe, bytecode enhanced ByteBuddy (the most complete in history) "

Realize your interview questions freely:

4000 pages of "Nin's Java Interview Collection" 40 topics

Please go to the official account of "Technical Freedom Circle" to get the PDF files of the above Nien architecture notes and interview questions↓↓↓

Guess you like

Origin blog.csdn.net/crazymakercircle/article/details/129998197