MySQL (5) lock


Computers use locks to coordinate concurrent access to a resource by multiple processes or threads. In a database, in addition to traditional competition for computing resources (CPU, RAM, I/O), data is also a resource shared by many users.
How to ensure the consistency, effectiveness and lock conflicts of concurrent data access is a problem that all databases must solve. Lock conflicts are also an important factor affecting the performance of database concurrent access.

Locks in MySQL are divided into the following three categories according to the granularity of the lock:
Global lock: locks all tables in the database.
Table-level lock: locks the entire table for each operation.
Row-level lock: Each operation locks the corresponding row data

global lock

The global lock locks the entire database instance. After the lock is locked, the entire instance is in a read-only state. Subsequent DML write statements, DDL statements, and transaction commit statements that have been updated will be blocked. A typical scenario is to make a logical backup of the entire database and lock all tables to obtain a consistent view and ensure data integrity.

A. If the full database data backup does not add a global lock, there may be problems.
Assume that there are tb_stock inventory table, tb_order order table, and tb_orderlog order log table in the database.
Insert image description here
When performing data backup, first back up the tb_stock inventory table, then perform the order operation, deduct the inventory, generate the order (update the tb_stock table, insert the tb_order table) and then execute the logic of backing up the tb_order table, and insert the order log during the business. Operation, finally, the tb_orderlog table is backed up. The data backed up in this way is inconsistent with the data in the tb_stock table and the tb_order table (there is order information for the latest operation, but the inventory has not been reduced), which needs to be solved with the help of MySQL's global lock.

B. Situation after adding a global lock.
Insert image description here
Before performing a logical backup of the database, first add a global lock to the entire database. Once the global lock is added, all other DDL and DML are blocked, but DQL statements can be executed. It is in a read-only state, and data backup is a query operation. During the process of logical backup of data, the data in the database will not change, thus ensuring the consistency and integrity of the data.

Add global lock

flush tables with read lock ;

Insert image description here
data backup

mysqldump -hip -uroot –p123456 itcast > itcast.sql

Insert image description here
release lock

unlock tables ;

Insert image description here

Features:
Adding a global lock to the database is a relatively heavy operation and has the following problems:

  • If the backup is performed on the main database, updates cannot be performed during the backup period, and the business will basically be shut down.
  • If the backup is performed on the slave database, the slave database cannot execute the binary log (binlog) synchronized from the master database during the backup period, which will cause master-slave delay.

In the InnoDB engine, we can add the --single-transaction parameter during backup to complete consistent data backup without locking.

mysqldump --single-transaction -uroot –p123456 itcast > itcast.sql

table level lock

Table-level locking locks the entire table for each operation. The locking granularity is large, the probability of lock conflict is the highest, and the concurrency is the lowest. Applied in storage engines such as MyISAM, InnoDB, and BDB.
For table-level locks, they are mainly divided into the following three categories:

  • table lock
  • Meta data lock (MDL)
  • intention lock

table lock

For table locks, they are divided into two categories:

  • Table shared read lock (read lock)
  • Table exclusive write lock (write lock)

grammar:

  • Locking: lock tables table name... read/write.
  • Release the lock: unlock tables / client disconnects.

A. Read lock
Insert image description here
Client 1 on the left has a read lock on the specified table. Client 1 cannot modify the table, which does not affect the reading of client 2 on the right, but will block the writing of the client on the right.

Test:
Client A adds a read lock:
Insert image description here
Client A queries data: √
Insert image description here
Client A modifies data: cannot be modified; releases the lock
Insert image description here
Client B queries data: √
Insert image description herek Client modifies data: blocked, requests A to release the lock and then modify it success
Insert image description here
Insert image description here

B. Write lock
Insert image description here
Client 1 is on the left, and a write lock is added to the specified table, which will block the reading and writing of the client on the right.

Test:
Client A adds write lock: Client A can modify and query data.
Insert image description here
Client B queries data: blocked. Query succeeds after client A releases the lock.
Insert image description here

Client B modified data: blocked. After client A released the lock, the modification was successful.
Insert image description here
Conclusion: The read lock will not block other clients' reading, but it will block writing. A write lock blocks both reading and writing by other clients.

metadata lock

meta data lock, metadata lock, abbreviation MDL. The MDL locking process is automatically controlled by the system and does not need to be used explicitly. It will be automatically added when a table is accessed. (Metadata can be simply understood as the table structure of a table. When a certain table involves uncommitted transactions, the table structure of this table cannot be modified.) Metadata locks prevent changes to table data. Change the table structure.

The main function of MDL lock is to maintain the data consistency of table metadata. When there are active transactions on the table, metadata cannot be written. In order to avoid conflicts between DML and DDL, ensure the correctness of reading and writing.

MDL was introduced in MySQL 5.5. When a table is added, deleted, modified, and checked, an MDL read lock (shared) is added; when a table structure is changed, an MDL write lock (exclusive) is added.

Metadata locks added during common SQL operations:
Insert image description here

Demonstration: When executing SELECT, INSERT, UPDATE, DELETE and other statements, metadata shared locks (SHARED_READ / SHARED_WRITE) are added
, which are compatible between them.
Insert image description here
When the SELECT statement is executed, the metadata shared lock (SHARED_READ) is added, which blocks the metadata exclusive lock (EXCLUSIVE), and they are mutually exclusive.
Insert image description here

Use the following SQL to check the metadata lock status in the database:

select object_type,object_schema,object_name,lock_type,lock_duration from performance_schema.metadata_locks ;

Insert image description here

intention lock

In order to avoid conflicts between row locks and table locks added when DML is executed, intention locks are introduced in InnoDB, so that table locks do not need to check whether each row of data is locked, and intention locks are used to reduce table lock checks.

If there is no intention lock, after the client adds row locks to a pair of tables, client 2 adds table locks to the table as follows:

First, client 1 starts a transaction and modifies the data based on the primary key id=3. At this time, a row lock will be automatically added to this row.
Insert image description here
When client 2 wants to add a table lock to this table, it will check whether the current table has a corresponding row lock. If not, it will add a table lock. At this time, it will check from the first row of data to the last row of data. Less efficient.
Insert image description here
After having the intention lock:
Client 1, when performing a DML operation, will add row locks to the rows involved, and will also add an intention lock to the table.
Insert image description here
When other clients add table locks to this table, they will determine whether the table lock can be successfully added based on the intention lock added to the table (compatible can add, incompatible wait), and there is no need to judge row locks row by row. Condition.
Insert image description here
Classification:

  • Intention shared lock (IS): added by the statement select ... lock in share mode. Before a transaction adds a shared lock to a row of records, it must first obtain the IS lock of the table. It is compatible with the table lock shared lock (read) and exclusive with the table lock. Lock (write) mutual exclusion.
  • Intention exclusive lock (IX): added by insert, update, delete, select...for update. Before adding an exclusive lock to a row of records, the transaction must first obtain the IX lock of the table and share the lock (read) and exclusive lock with the table lock. (write) are mutually exclusive, and intention locks are not mutually exclusive.

Once the transaction is committed, the intention shared lock and the intention exclusive lock will be automatically released.
Insert image description here

  • Before adding a row lock, the InnoDB storage engine automatically adds the IS or IX lock of the table. We cannot manually obtain the IS or IX lock.
  • Intention locks are compatible with each other and will not cause conflicts.
  • The purpose of intention locks is to obtain table locks more efficiently (X, S, IX, IS in the table refer to table locks, not row locks)
  • Intention locks are table-level locks that coordinate the coexistence of table locks and row locks. Their main purpose is to show that a transaction is locking a row or trying to lock a row.

Use the following SQL to check the locking status of intention locks and row locks:

select object_schema(),object_name(),index_name(索引名称),lock_type(锁范围),lock_mode(锁类型),lock_data(被加锁数据/索引项) from performance_schema.data_locks;

演示:
A. 意向共享锁与表读锁是兼容的

After executing the select id=1 statement, a row lock (shared lock) will be added to id=1 (recorded represents a row lock), and an IS (intention shared lock) will be added to the table.

select * from score where id =1 lock in share mode;

Insert image description here
The read lock was added successfully
Insert image description here
and the write lock was blocked.
Insert image description here

B. Intent exclusive locks are mutually exclusive with table read locks and write locks.

After executing the update id=1 statement, a row lock (exclusive lock) will be added to id=1(recorded) and an IX (intention exclusive lock) will be added to the table.

update score set math = 66 where id =1;

Insert image description here
Add read lock blocking
Insert image description here

row level lock

Row-level locking locks the corresponding row data for each operation. The locking granularity is the smallest, the probability of lock conflicts is the lowest, and the concurrency is the highest. Applied in InnoDB storage engine.

InnoDB data is organized based on indexes, and row locks are implemented by locking index entries on the index , rather than locking records. For row-level locks, they are mainly divided into the following three categories:

  • Row Lock (Record Lock): Locks a single row of records to prevent other transactions from updating and deleting the row. Supported at both RC (Read Commit) and RR isolation (reaptablt read) levels.
    Insert image description here
  • Gap Lock: Locks the index record gap (excluding the record) to ensure that the index record gap remains unchanged and prevents other transactions from inserting in this gap and causing phantom reads. It is supported under the RR (reaptablt read) isolation level.
    Insert image description here
  • Next-Key Lock: A combination of row lock and gap lock, locking the data at the same time and locking the gap in front of the data. Supported under RR (reaptablt read) isolation level.
    Insert image description here

row lock

InnoDB implements the following two types of row locks:
Shared lock (S): an exclusive lock that allows one transaction to read a row and prevents other transactions from obtaining the same data set.
Exclusive lock (X): Allows the transaction that acquires the exclusive lock to update data, and prevents other transactions from acquiring shared locks and exclusive locks on the same data set.

The compatibility of the two row locks is as follows:
Insert image description here
common SQL statements, when executed, the row locks added are as follows:
Insert image description here
By default, InnoDB runs at the REPEATABLE READ transaction isolation level, and InnoDB uses next-key (part) locks for search and Index scan to prevent phantom reads.

  • When retrieving against a unique index, equivalent matching of existing records will be automatically optimized for row locking.
  • InnoDB's row lock is a lock added to the index. If data is not retrieved through index conditions, InnoDB will lock all records in the table, and it will be upgraded to a table lock.

data preparation:

CREATE TABLE `stu` (
	`id` int NOT NULL PRIMARY KEY AUTO_INCREMENT,
	`name` varchar(255) DEFAULT NULL,
	`age` int NOT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4;

INSERT INTO `stu` VALUES (1, 'tom', 1);
INSERT INTO `stu` VALUES (3, 'cat', 3);
INSERT INTO `stu` VALUES (8, 'rose', 8);
INSERT INTO `stu` VALUES (11, 'jetty', 11);
INSERT INTO `stu` VALUES (19, 'lily', 19);
INSERT INTO `stu` VALUES (25, 'luci', 25);

You can check the locking status of intention locks and row locks through the following SQL:

select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;

A. Ordinary select statements will not be locked when executed.
Insert image description here
B. Select…lock in share mode, add shared lock, shared lock is compatible with shared lock.
REC_NOT_GAP means there is no gap
Insert image description here
. Both clients add shared locks and are compatible.
Insert image description here
Shared locks and exclusive locks are incompatible.

Client 1 acquires the shared lock for the row with ID 1, and Client 2 acquires the exclusive lock for the row with ID 3. Because they are not the same row of data, they can be acquired without blocking. And if client 2 wants to obtain the exclusive lock on the row with id 1, it will be blocked because the shared lock and the exclusive lock are mutually exclusive.
Insert image description here
C. Mutual exclusion between exclusive locks and exclusive locks.
When client 1 executes the update statement to update the data with id 1, an exclusive lock will be added to the record with id 1; client 2, if the update statement is also executed to update the data with id 1 For the data, an exclusive lock must also be added to the data with id 1. Client 2 will be in a blocked state because the exclusive locks are mutually exclusive. The row lock on this row will not be released until client one commits the transaction. At this time, client two is unblocked.
Insert image description here
D. The indexless row lock is upgraded to a table lock.
The data in the stu table is as follows:
Insert image description here
In client one, start the transaction and execute the update statement to update the data named Lily. Client 2 updates the record with ID 3, but cannot execute it directly. It will be in a blocked state because client 1 updates based on the name field. The name field has no index. If there is no index, the row lock will be upgraded to the table. Lock (because the row lock is a lock on the index item, and name has no index).
Insert image description here
Create an index on the name field. After the index is established, do a test again:

Client 1: When opening a transaction, it is still updated based on the name. When client two updated the data with ID 3, the update was successful and did not enter the blocking state. This means that updating operations based on index fields can avoid row locks being upgraded to table locks.
Insert image description here

Gap lock & key lock

By default, InnoDB runs at the REPEATABLE READ transaction isolation level. InnoDB uses next-key (next-key) locks for searches and index scans to prevent phantom reads .

  • When equivalent queries on indexes (unique indexes) lock non-existent records, they are optimized to gap locks.
  • For equivalent queries on indexes (non-unique ordinary indexes), when the last value does not meet the query requirements during right traversal, the next-key lock degenerates into a gap lock.
  • Range queries on indexes (unique indexes) – access until the first value that does not satisfy the condition.

Note: The only purpose of gap locks is to prevent other transactions from inserting gaps. Gap locks can coexist, and a gap lock taken by one transaction does not prevent another transaction from taking a gap lock on the same gap.

Example Demonstration
A. Equivalent query on the index (unique index), when locking non-existent records, optimize to gap lock.
Client A starts a transaction and modifies the record with id=5. The record with id=5 does not exist. At this time, gap locks will be added to 3-8. If client B adds data with id=7, it will be blocked and wait for the transaction. After submission, client B's addition operation is successful.
Insert image description here
B. For equivalent queries on indexes (non-unique ordinary indexes), when the last value does not meet the query requirements when traversing to the right, the next-key lock degenerates into a gap lock.

InnoDB's B+ tree index, the leaf nodes are ordered doubly linked lists. If we query the data with a value of 18 based on this secondary index and add a shared lock, is it enough to only lock the row 18? No, because it is a non-unique index, data with a value of 18 may be inserted before and after 18. Therefore, when locking, it will continue to search later and find a value that does not meet the conditions (in the current case, it is 29, no is a value of 18). At this time, a key lock will be added to 18, and the gap before 29 will be locked.
Insert image description here
The table data is as follows:
Insert image description here
Add a normal index to the age field, add an intention lock when querying age=3, and query the locking situation of the InnoDB engine:
13, 3: According to the age index, the gap lock before the record with id=3 Live
3: On the primary key index, the row record
18 with id=3 is locked. 8: According to the age index, the gap before the record with id=8 is locked,
that is, the row record with id=3 is added. Lock, lock the gap before and after age=13, to avoid phantom reading when other transactions add another record in 13-18.
Insert image description here
C. Range query on the index (unique index) – will access the first value that does not meet the condition.

The query condition is id>=19, and a shared lock is added. At this time, we can divide the data into three parts based on the existing data in the database table: [19], (19,25], (25,+∞], so when the database data is locked, 19 is added The row lock, the adjacent key lock of 25 (including 25 and the gap before 25), and the adjacent key lock of positive infinity (positive infinity and the gap before it). That is, all the data from 19 to positive infinity are locked.
Insert image description here

Summarize

Locks are used to solve the consistency and validity issues of data access during concurrent access.
Divided into: global lock, table-level lock, row-level lock

  • Global lock: Lock the entire database instance. After locking, the entire instance is in a read-only state and has poor performance. It is used for logical data backup.
  • Table-level lock: locks the entire table, the locking granularity is large, and the probability of send lock conflict is high: table lock, metadata lock, intention lock
  • Row-level lock: locks the row data of the corresponding operation. The locking granularity is the smallest and the probability of lock conflict is the lowest. It is divided into row lock, gap lock and temporary lock.

Guess you like

Origin blog.csdn.net/weixin_43994244/article/details/129426514