MySQL Advanced - MVCC Multi-Version Concurrency Control

 navigation: 

[Dark Horse Java Notes + Stepping on the Pit Summary] JavaSE+JavaWeb+SSM+SpringBoot+Riji Takeaway+SpringCloud+Dark Horse Tourism+Guli Mall+Xuecheng Online+MySQL Advanced Chapter+Design Mode+Nioke Interview Questions

Table of contents

1. What is MVCC

2. Snapshot read and current read

2.1 Snapshot read

2.2 Current reading

3. MVCC Three Musketeers

3.1 Review isolation levels

3.2 Hidden fields, Undo Log version chain

3.3 ReadView

3.3.1 ReadView (reading view) simplified version

3.3.2 Design ideas

3.3.3 Rules of ReadView

3.3.4 MVCC overall operation process

4. Give an example to illustrate the MVCC process

4.1 Read the submitted MVCC process

4.2 Repeatable read MVCC process 

4.3 InnoDB solves phantom reading problem

5. Summary


1. What is MVCC

Multi-version concurrency control, by managing multiple versions of records, achieves consistent reading when database transactions are concurrent, that is, when the current transaction reads a row that is being updated by other transactions, it can read the version before the record is updated. Read and write conflicts are resolved. 

MVCC (Multiversion Concurrency Control), multi-version concurrency control . As the name implies, MVCC implements database concurrency control through multiple version management of data rows. This technique enables consistent read operations to be performed under InnoDB's transaction isolation level . In other words, it is to query some rows that are being updated by another transaction, and you can see their values ​​before they are updated , so that you don't have to wait for another transaction to release the lock when doing the query.

There is no formal standard for MVCC . The implementation of MVCC may be different in different DBMS (database management systems), and it is not commonly used (you can refer to related DBMS documents). Here is an explanation of the implementation mechanism of MVCC in InnoDB (other storage engines of MySQL do not support it).

2. Snapshot read and current read

Snapshot reading: The implementation of MVCC in MySQLInnoDB is mainly to improve the concurrency performance of the database, and to deal with read-write conflicts in a better way, so that even when there are read-write conflicts, it can also be read without locking and non-blocking concurrent read , and this read refers to the snapshot read , not the current read. The essence of MVCC is a way to adopt the idea of ​​​​optimistic locking .

The current read is actually a locking operation, which is the implementation of pessimistic locking.

2.1 Snapshot read

Snapshot read, also called consistent read, reads snapshot data. Simple SELECTs without locks are all snapshot reads, that is, non-blocking reads without locks ; for example:

SELECT * FROM player WHERE ...

The reason why snapshot reading occurs is based on the consideration of improving concurrency performance. The implementation of snapshot reading is based on MVCC. In many cases, it avoids locking operations and reduces overhead.

Since it is based on multiple versions, the snapshot read may not necessarily read the latest version of the data , but may be the previous historical version.

The premise of snapshot reading is that the isolation level is not serial level, and snapshot reading at the serial level will degenerate into current reading.

2.2 Current reading

The current read reads the latest version of the record ( the latest data, not the historical version of the data ). When reading, it must be ensured that other concurrent transactions cannot modify the current record, and the read record will be locked . Locked SELECT, or adding, deleting, and modifying data will all be read currently. for example:

SELECT * FROM student LOCK IN SHARE MODE; # 共享锁
SELECT * FROM student FOR UPDATE; # 排他锁
INSERT INTO student values ... # 排他锁
DELETE FROM student WHERE ... # 排他锁
UPDATE student SET ... # 排他锁

3. MVCC Three Musketeers

3.1 Review isolation levels

Transaction isolation level refers to the degree of isolation between concurrent transactions operating on the same resource. The higher the isolation level, the smaller the mutual interference between transactions, and the higher the security.

Read the question:

  • Dirty read: read dirty data. The current transaction reads data just changed by another uncommitted transaction. Only read uncommitted will be dirty read.
  • Non-repeatable read: The data read repeatedly before and after are not the same. The same data is read twice before and after. During this period, the data is changed by other transactions, resulting in different data read before and after.
  • Phantom reading: The data read before and after are the same, but there are a few more lines or a few less lines, like an illusion. The data sets read before and after the transaction are different, resulting in "phantom" rows. Only serialization can solve the phantom read problem.

transaction isolation level

  • Read uncommitted: The transaction can read all uncommitted transaction data. There is no lock or isolation at all, and the performance is the highest.
  • Read Commit: Transactions can read the data of committed transactions. The bottom layer is implemented by MVVC, and each snapshot read generates a read view. Solve the dirty read problem.
  • Repeatable read (default): The same data is read before and after. The bottom layer is implemented by MVVC, and only the first snapshot read generates a read view. Solve the problem of dirty read and non-repeatable read. The repeatable read of the MySQL InnoDB engine solves the phantom read problem. The snapshot read is solved by MVCC, and the current read is solved by next-key lock.
  • Serialization: Once a transaction acquires a lock, it blocks other transactions until the lock is released. Shared lock for reading and exclusive lock for writing. Blocking results in the worst performance. Solve the problems of dirty reads, non-repeatable reads, and phantom reads. 

MVVC: Multiversion Concurrency Control. MVCC Three Musketeers: Hidden Fields, Undo Log, Read View.

Shared lock (read lock): Under shared lock, multiple threads can read data at the same time, but only one thread can modify data. When a thread is modifying data, it must acquire an exclusive lock so that other threads cannot access the data.

Exclusive lock (write lock): Under an exclusive lock, only one thread can modify the data, and other threads are not allowed to access the data.

MVCC can solve the problem of non-repeatable reading and phantom reading through optimistic locking instead of using locking mechanism! It can replace row-level locking in most cases and reduce system overhead

3.2 Hidden fields, Undo Log version chain

hidden field 

For tables using the InnoDB storage engine, its clustered index records contain two necessary hidden columns .

  • trx_id (transaction id): Every time a transaction changes a certain clustered index record , the transaction assigned to the trx_id hidden column.
  • roll_pointer (rollback pointer): points to the nearest node of the record version chain in the undo log. Every time a clustered index record is modified , the old version will be written into the undo log  , and then this hidden column is equivalent to a pointer , through which the information before the modification of the record can be found .

Undo Log (rollback log)

When a transaction performs a write operation on the database, MySQL will first write the old version of the data to be modified into the Undo Log , and then write the new version of the data into the database . Before the transaction is committed, the data in the Undo Log can be used for rollback ; after the transaction is committed, the old version data in the Undo Log can also be used to provide the historical version data of the read operation.

Undo Log (rollback log) version chain

In the implementation of MySQL, the Undo Log version chain is used to maintain the historical version of the data , and the data used when  rolling back and reading the historical version .

The version chain of Undo Log is a linked list used to maintain these historical version data .

In the Undo Log version chain, each version corresponds to a version number or timestamp , and new version data will be added to the head of the version chain. At the same time, the Undo Log version chain can also maintain different versions of data between multiple transactions through a pointer structure similar to a linked list.

For read operations, if you need to read historical version data, MySQL can obtain data under the specified version by accessing the Undo Log version chain. For the rollback operation, MySQL can simply restore the corresponding version of data in the Undo Log, from

case: 

Assuming that the transaction id of inserting this record is 8, the schematic diagram of this record at this moment is as follows: 

Insert undo only works when the transaction is rolled back. After the transaction is committed, this type of undo log is useless , and the Undo Log Segment it occupies will also be recycled by the system (that is, the Undo page linked list occupied by the undo log is either deleted. reuse, or be released).

10Assume that the next two transactions whose transaction IDs are respectively 20and operate on this record UPDATE, the operation process is as follows:

Can you cross-update the same record in two transactions?

No! This is not that one transaction modifies the data modified by another uncommitted transaction, dirty write.

lnnoDB uses locks to ensure that there will be no dirty writes , that is, after the first transaction updates a record, it will lock the record, and another transaction needs to wait for the first transaction when it is updated again After submitting, the update can only be continued after the lock is released. 

Every time a record is changed, an undo log will be recorded, and each undo log also has a roll_pointer attribute (the undo log corresponding to the INSERT operation does not have this attribute, because the record does not have an earlier version), and these undo logs can be Connect them all together to form a linked list:

Every time the record is updated, the old value will be put into an undo log. Even if it is an old version of the record, as the number of updates increases, all versions will be connected into a linked list by the roll_pointer attribute. We put this The linked list is called a version chain, and the head node of the version chain is the latest value of the current record .

Each version also contains the corresponding transaction id when the version was generated.

3.3 ReadView

The implementation of MVCC depends on: hidden fields, Undo Log, Read View.

3.3.1 ReadView (reading view) simplified version

Read View is a read view produced when a transaction performs a snapshot read operation . At the moment when the transaction executes a snapshot read, a current snapshot of the data system will be generated, and the id of the current active transaction in the system will be recorded and maintained . The id value of the transaction is incremented of .

In fact, the biggest function of Read View is to make visibility judgments , that is to say, when a transaction is performing snapshot reading, create a Read View view of the record, and use this read view as a condition to judge the current transaction Which version of the data can be seen , it is possible to read the latest data, or it is possible to read the data of a certain version in the undolog recorded in the current line

First of all, you need to know the global properties in Read View:

  • creator_trx_id : ID of the transaction that created this read view . Addition, deletion and modification transactions are eligible to be assigned an id, and the read transaction id is 0.
  • trx_ids: Indicates the transaction id list of active read and write transactions in the current system when ReadView is generated .
  • up_limit_id: record the smallest transaction ID in the active transaction list . The smallest is the earliest.
  • low_limit_id: Indicates the id value that should be assigned to the next transaction in the system when ReadView is generated . will be the largest id in the list.

The rules of Read View, that is, the visibility algorithm:

By reading the view, you can determine whether a certain version of the record is visible in the current query.

The judgment method is to compare the trx_id of each version with the active transaction id in the read view. If the trx_id of a certain version is smaller than the minimum transaction id of the read view, it means that version is the submitted version before the read view is generated, and the current query can access that version .

MVCC process:

Query, generate a read view, use the active transaction id of the read view to compare the transaction ids of each version in turn, and find the data that meets the rules.

Application: The bottom layer of read commit and repeatable read in the transaction isolation level is implemented by MVCC. And the repeatable reading of the MySQL InnoDB engine solves the problem of phantom reading by MVCC.

The MVCC principle of read commit: each transaction reads the latest committed data. Generate a ReadView every time before reading data. Snapshot reading generates Read View, and continuously compares the trx_id of each version chain until it finds that a certain version trx_id is smaller than the smallest trx_id in the active transaction list of Read View, and this version is the latest submitted data before snapshot reading.

The MVCC principle of repeatable reading: ReadView is only generated during the first query, and the ReadView generated during the first snapshot read is used for subsequent queries.

In the MVCC mechanism, multiple transactions updating the same row record will generate multiple historical snapshots, which are stored in the Undo Log . If a transaction wants to query this row record, which version of the row record needs to be read? At this time, Readview is needed, which helps us solve the problem of row visibility.

ReadView is the read view generated when a transaction uses the MVCC mechanism for snapshot read operations . When a transaction is started, a current snapshot of the database system will be generated. lnnoDB constructs an array for each transaction to record and maintain the ID of the current active ("active" means that it has been started but not submitted yet ) . 

3.3.2 Design ideas

For transactions using the READ UNCOMMITTED isolation level, since records modified by uncommitted transactions can be read, it is good to directly read the latest version of the records.

For transactions using the SERIALIZABLE isolation level, InnoDB specifies the use of locks to access records.

Transactions using the READ COMMITTED and REPEATABLE READ isolation levels must ensure that they read the records modified by the committed transaction. If another transaction has modified the record but has not submitted it, the latest version of the record cannot be read directly. The core problem is to determine which version in the version chain is visible to the current transaction. This is the main problem to be solved by ReadView.

This ReadView mainly contains 4 more important contents, as follows:

  1. creator_trx_id, create the transaction ID of this Read View.

    Note: Only when the records in the table are changed (when statements such as INSERT, DELETE, and UPDATE are executed), the transaction id will be assigned to the transaction, otherwise the transaction id value in a read-only transaction defaults to 0.

  2. trx_ids , indicating the transaction id list of active read and write transactions in the current system when ReadView is generated.

  3. up_limit_id , the smallest transaction ID among active transactions.

  4. low_limit_id, indicating the id value that should be assigned to the next transaction in the system when ReadView is generated. low_limit_id is the maximum transaction id value in the system. It should be noted here that the transaction id in the system needs to be distinguished from the active transaction id.

Note: low_limit_id is not the maximum value in trx_ids, and transaction ids are allocated incrementally. For example, now there are three transactions with id 1, 2, and 3, and then the transaction with id 3 is submitted. Then when a new read transaction generates ReadView, trx_ids includes 1 and 2, the value of up_limit_id is 1, and the value of low_limit_id is 4.

  • creator_trx_id : ID of the transaction that created this read view . Addition, deletion and modification transactions are eligible to be assigned an id, and the read transaction id is 0.
  • trx_ids: Indicates the transaction id list of active read and write transactions in the current system when ReadView is generated .
  • up_limit_id: record the smallest transaction ID in the active transaction list . The smallest is the earliest.
  • low_limit_id: Indicates the id value that should be assigned to the next transaction in the system when ReadView is generated . will be the largest id in the list.

3.3.3 Rules of ReadView

With this ReadView, when the current transaction accesses a record , it only needs to follow the steps below to determine whether a certain version of the record is visible.

  • If the trx_id attribute value of the accessed version is the same as the creator_trx_id value in ReadView, it means that the current transaction is accessing its own modified records, so this version can be accessed by the current transaction.
  • If the trx_id attribute value of the accessed version is smaller than the up_limit_id value in ReadView, it indicates that the transaction that generated this version has been committed before the current transaction generates ReadView, so this version can be accessed by the current transaction.
  • If the trx_id attribute value of the accessed version is greater than or equal to the low_limit_id value in ReadView, it indicates that the transaction that generates this version is started after the current transaction generates ReadView, so this version cannot be accessed by the current transaction.
  • If the trx_id attribute value of the accessed version is between the up_limit_id and low_limit_id of ReadView, it is necessary to determine whether the trx_id attribute value is in the trx_ids list.
    • If it is, it means that the transaction that generated this version was still active when ReadView was created, and this version cannot be accessed.
    • If not, it means that the transaction that generated this version has been submitted when ReadView was created, and this version can be accessed.

3.3.4 MVCC overall operation process

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. getReadView;
  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.

If the data of a certain version is not visible to the current transaction, follow the version chain to find the data of the next version, continue to judge the visibility according to the above steps, and so on, until the last version in the version chain. If the last version is also not visible, it means that the record is completely invisible to the transaction, and the query result does not include the record.
In InnoDB, MVCC reads data through Undo Log + Read View. Undo Log saves historical snapshots, and the Read View rule helps us determine whether the current version of the data is visible.  

When the isolation level is Read Committed (Read Committed), each SELECT query in a transaction will reacquire the Read View once.

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 repeatable read, non-repeatable read is avoided. This is because a transaction only obtains a Read View at the first SELECT, and all subsequent SELECTs will reuse this Read View, as shown in the following table Shown:

4. Give an example to illustrate the MVCC process

4.1 Read the submitted MVCC process

Read Commit: Each transaction reads the latest committed data. The bottom layer is implemented by MVVC, and a ReadView is generated every time before data is read. Only solves the dirty read problem.

 The MVCC principle of read submission: Read View is generated for each read, and the trx_id of each version of the version chain is continuously compared until a certain version trx_id is found to be smaller than the smallest trx_id in the active transaction list of Read View. This version is the latest submitted 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;
# 更新了一些别的表的记录
...

Note: 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. That's why we update some records in other tables in transaction 2, in order to let it assign a transaction id.

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 READ COMMITTED isolation level starts to execute:

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

# SELECT1:Transaction 10、20未提交
SELECT * FROM student WHERE id = 1; # 得到的列name的值为'张三',对应事务id为8

The execution process of this SELECT1 is as follows:

  1. A ReadView is first generated when executing a SELECT statement (snapshot read) . The content of the trx_ids list of ReadView is [10, 20] . up_limit_id is 10, low_limit_id is 21, creator_trx_id is 0.
  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 Wang Wu . The trx_id value of this version is 10 , which is in the trx_ids list , so it does not meet the visibility requirements . Jump to according to the roll_pointer next version.
  3. The content of the column name in the next version is Lisi. The trx_id value of this version is also 10, which is also in the trx_ids list, so it does not meet the requirements, so continue to skip to the next version.
  4. The content of the column name of the next version is Zhang San . The trx_id value of this version is 8 , which is less than the minimum active transaction up_limit_id value of 10 in ReadView , indicating that this version is the latest version before ReadView is generated , so this version meets the requirements , the final version returned to the user is the record whose column name is Zhang San.

After that, 事务idwe 10submit the transaction for :

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

Then go 事务idto 20the transaction for and studentupdate the record forid in the table:1

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

At this moment, the version chain idof 1looks like this:

Then continue to look for the record with id 1 in the transaction that just used READ COMMITTEDthe isolation level, 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

  1.  When the SELECT statement is executed, a ReadView will be generated separately . The content of the trx_ids list of the ReadView [20] is that the up_limit_id is 20, the low_limit_id is 21, and the creator_trx_id is 0.
  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 8. The trx_id value of this version is 20, which is in the trx_ids list, so it does not meet the visibility requirements. Jump according to roll_pointer to the next version.
  3. The content of the column name in the next version is Qianqi', and the trx_id value of this version is 28, which is also in the trx_ids list, so it does not meet the requirements, so continue to skip to the next version.
  4. The content of the column name in the next version is 'Wang Wu' , the trx_id value of this version is 10, which is smaller than the up_limit_id value 28 in ReadView, so this version meets the requirements, and the final version returned to the user is this column name as , Wang V' records. 

4.2 Repeatable read MVCC process 

The ReadView is only generated during the first query , and the ReadView generated during the first snapshot read is used for subsequent queries.

For example, there are two transactions in the system 事务idwhich are respectively 10are executing:20

# 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 REPEATABLE READthe isolation executed:

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

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

The execution process of this SELECT1 is as follows:

  1. When the SELECT statement is executed, a Readview will be generated first, and the content of the trx_ids list of the ReadView is [10, 20].up_limit_id is 10, low_limit_id is 21, and creator_trx_id is 0.
  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 "Wang Wu". The trx_id value of this version is 10, which is in the trx_ids list, so it does not meet the visibility requirements. According to rol1_pointer skips to the next version.
  3. The content of the column name in the next version is, Lisi', and the trx_id value of this version is also 10, which is also in the trx_ids list, so it does not meet the requirements, so continue to skip to the next version.
  4. The content of the column name in the next version is 'Zhang San'. The trx_id value of this version is 8, which is smaller than the up_limit_id value of 10 in Readview, so this version meets the requirements. The final version returned to the user is this column name as , Zhang San's record.

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 idin the table student is as follows:1

Then go to the transaction that just used REPEATABLE READthe isolation level to continue to find the record forid , as follows:1

# 使用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 SELECT2 is as follows:

  1. Because the isolation level of the current transaction is REPEATABLE READ, and ReadView has been generated before executing SELECT1, so the previous ReadView is directly reused at this time . The content of the trx_ids list of the previous ReadView is [10, 20], and the up_limit_id is 1 , low_limit_id is 21, creator_trx_id is 0
  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', and the trx_id value of this version is 29, which is in the trx_ds list, so it does not meet the visibility requirements. According to ro11 pointer skip to next version
  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, so continue to skip to the next version.
  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, and the next column name is the same The content is that Li Si's version does not meet the requirements. continue to skip to the next version
  5. The content of the column name in the next version is 'Zhang San', and the trx_id value of this version is 80, which is smaller than the up_limit_id value of 18 in ReadView, so this version meets the requirements, and the final version returned to the user is this column c as , Zhang San's record.

The result of this SELECT query is repeated , 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 transaction id 20 later, and then continue to search for the record with id 1 in the transaction that used the REPEATABLE READ isolation level just now, the result is still Zhang San. You can analyze the specific execution process by yourself .

4.3 InnoDB solves phantom reading problem

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.

5. Summary

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.

Explanation: We said before that executing the DELETE statement or the UPDATE statement that updates the primary key will not immediately delete the corresponding record from the page but execute a so-called delete mark operation, which is equivalent to marking a delete mark on the record. Mainly for the MVCC service.

Through MVCC we can solve:

  • 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.
  • The probability of deadlock is reduced. 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.
  • Solve the problem of snapshot read. 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.

Guess you like

Origin blog.csdn.net/qq_40991313/article/details/130462818