Look at the following SQL statement:
# table T (id int, name varchar(20))delete from T where id = 10;Copy the code
select * from T whereId = 10;Copy the code
Introduction to relevant knowledge
Multi-version concurrency control
The default storage engine for MySQL, InnoDB, is a multi-version Concurrency Control protocol (MVCC). The opposite of MVVC is the Lock-based Concurrency Control. The biggest advantage of MVCC is: read without lock, read and write without conflict. In OLTP applications with more read and less write, read and write conflict is very important, which greatly improves the concurrency performance of the system. At present, almost all RDBMS support MVCC. In fact, MVCC is summed up in one sentence: a way to temporarily store multiple versions of the same data, thereby achieving concurrency control.
Current read and snapshot read
Snapshot read (simple SELECT operation) : Reads the visible version (possibly historical version) of the record without locking. There you have the answer to the second question.
Clustered index
Left-most prefix rule
Two phase lock
Isolation level
Gap and next-key locks
analysis
-
Premise 1: Is the ID column a primary key?
-
Premise two: What is the current system isolation level?
-
If the id column is not a primary key, do you have an index on the ID column?
-
Premise 4: If there is a secondary index on the ID column, is it unique?
-
Premise five: What is the SQL execution plan? Index scan? Full table scan again
-
The ID column is the primary key, RC isolation level
-
The ID column is a secondary unique index, RC isolation level
-
The ID column is a secondary non-unique index, RC isolation level
-
No index on id column, RC isolation level
-
The ID column is the primary key, RR isolation level
-
The ID column is a secondary unique index, RR isolation level
-
The ID column is a secondary non-unique index, RR isolation level
-
No index on id column, RR isolation level
This combination is the easiest to parse, and by the time the statement is executed, only records with primary key ID = 10 need to be x-locked. As shown below:
Combination two: id unique index + RC
Combination 3: id not unique index +RC
Conclusion: If there is a non-unique index on the ID column, then all records that meet the SQL query criteria will be locked. These records are also locked on the primary key index.
Select * from where id = 10; select * from where id = 10; select * from where id = 10; How does MySQL lock this combination? See below:
MySQL > select * from ‘id’; MySQL > select * from ‘id’; Because it’s at the MySQl Server level. Therefore, every record, regardless of whether it meets the filtering conditions, will be added with the X lock. However, for efficiency, MySQL has improved this aspect. During the scanning process, if the record does not meet the filtering conditions, it will be unlocked. Optimization also violates the 2PL principle.
Combination 6: ID unique index +RR
Combination 7: ID not unique index +RR
So how to solve this problem? How to ensure that multiple current reads return consistent records requires that no new records that meet the condition are inserted and committed by other transactions between multiple current reads. In order to achieve this result, Gap lock came into being.
In combination 5, combination 6, the same RR level, but do not add Gap lock, combination 5 id is the primary key, combination 6 ID is Unique key, can guarantee the uniqueness. An equivalent query can only return one record that meets the condition at most, and new records of the same value cannot be inserted.
Combination 8: ID No index +RR
Of course, like combination four, MySQL has been optimized to be semi-consistent Read. Semi-consistent Read If semi-Consistent Read is enabled, MySQL will release the lock in advance for records that do not meet the criteria, and the Gap lock will also be released. Semi-consistent Read is triggered either at the Read Committed isolation level; Either innodb_LOCKS_unSAFE_for_binlog is set in Repeatable Read isolation level.
Conclusion: In Repeatable Read isolation level, if the current Read of the full table scan is performed, all records on the table will be locked, and all gaps will be locked by Gap, eliminating all delete/update/ INSERT operations. Semi -consistent Read can be triggered in MySQL to alleviate lock overhead and concurrency, but semi-consistent Read itself brings other problems and is not recommended.
In the final combination, the locking process is the same as in combination eight for the delete SQL statement of appeal. However, query statements (for example, select * from T1 where ID = 10) are read by snapshots at the RC and RR isolation levels and are not locked. At the Serializable isolation level, no matter the query statement is locked, that is, the snapshot read does not exist, and the MVCC is degraded to lock-based CC.