"MySQL": Introduction to MySQL Locking Mechanism

Table of contents

I. Overview

2. Global lock

3. Table-level lock

3. Row-level locks


I. Overview

A lock is a mechanism by which a computer coordinates concurrent access to a resource by multiple processes or threads. In a database, in addition to the contention of traditional computing resources (CPU, RAM, I/O), data is also a resource shared by many users. How to ensure the consistency and validity of concurrent access to data is a problem that all databases must solve, and lock conflicts are also an important factor affecting the performance of concurrent access to databases. From this perspective, locks are particularly important and more complex for databases.

The 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: each operation locks the entire table
  • Row-level lock: Each operation locks the corresponding row data.

2. Global lock

a. Introduction

The global lock is to lock the entire instance of the database. After locking, the entire instance is in a read-only state. Subsequent DML write statements, DDL statements, and transaction commit statements for update operations will be blocked. The typical usage scenario of the global lock is to perform The logical backup of the whole database locks all tables to obtain a consistent view and ensure data integrity.

Why add a global lock when performing a full database backup?

Let's use a simple example to introduce the problems that may arise when global locks are not added.

Suppose there are three tables in the database, tb_stock inventory table, tb_order order table, tb_orderlog order log table.

When performing data backup:

  • Back up the tb_stock table first
  • Then, in the business system, the order is placed, the inventory is deducted, and the order is generated (update the tb_stock table and insert the tb_order table)
  • Then execute the logic of backing up the tb_order table
  • The operation of inserting into the order log in the business
  • Finally, the tb_orderlog table is backed up

In the above execution process, there is a problem with the backed up data, because the backed up data, the tb_stock table and the tb_order table have data inconsistencies, and there is the latest order information, but the total inventory has not changed

So how to avoid this phenomenon of data inconsistency? At this time, you need to use MySQL's global lock to solve it:

At this point, let's analyze the situation after adding the global lock:

Before the logical backup of the database, first add a global lock to the database. Once the global lock is added, all other DDL and DML are in a blocked state.

However, DQL statements can be executed, that is, read-only status, and data backup is a query operation, so during the data backup process, the data in the database will not change, thus ensuring data integrity and consistency.

b. to operate

  • Add global lock
flush tables with read lock;
  • data backup
mysqldump -uroot –p1234 itcast > itcast.sql
  • release lock
unlock tables;

c. Features

If a global lock is added to the database, it is a relatively heavy-grained operation, which is prone to the following problems:

  • If the backup is performed on the main library, the update operation cannot be performed during the backup period, and the business is basically at a standstill
  • If the backup is performed on the slave library, during the backup period, the slave library cannot execute the binary files synchronized from the master library, which will cause master-slave delay.

In the InnoDB engine, an unlocked data consistency backup can be completed by adding a parameter during backup

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

3. Table-level lock

Table-level locks, as the name suggests, can lock the entire table for each operation. The locking granularity is large, the probability of lock conflicts is high, and the concurrency is the lowest. It is usually used in InnoDB, MyISAM, BDB and other engines. Here we only use InnoDB Detailed explanation of table-level locks:

1. Table lock

For table-level locks, they are mainly divided into the following three categories:

  1. table lock
  2. metadata lock
  3. intent lock

For table locks, there are mainly two types

  1. Table shared read lock (read lock)

Features: After adding a read lock to the specified table, when client one performs a read operation, it will not affect the read operation of client two, but it will block the write operation of the two clients.

  1. Table exclusive write lock (write lock)

After an exclusive write lock is added to the specified table, client 1 can read and write to the table, while client 2's read and write will be blocked

grammar:

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

Summary: Read locks will not block other clients' reads, but will block writes, and write locks will block both other clients' reads and other clients' writes.

2. Metadata lock

Metadata lock, abbreviated as MDL. The MDL locking process is automatically controlled by the system and does not need to be used explicitly. It will be added automatically when accessing a table. The main function of the MDL lock is to maintain the data consistency of the table metadata. When there are active transactions on the table, the metadata cannot be written. In order to avoid conflicts between DML and DDL, ensure the correctness of reading and writing .

The metadata here can be simply understood as the table structure of a table. That is to say, when a certain table involves uncommitted transactions, the table structure of this table cannot be modified.

MDL was introduced in MySQL5.5. When adding, deleting, modifying and querying a table, add MDL read lock (shared); when changing the table structure, add MDL write lock (exclusive).

Then if the database has a long transaction (the so-called long transaction means that the transaction has been opened but has not been submitted), then when the table structure is changed, unexpected things may happen, such as the following sequence scene :

  1. First of all, thread A first enables the transaction (but has not submitted it), and then executes a select statement, at this time, the MDL read lock is first added to the table;
  2. Then, thread B also executes the same select statement, and it will not block at this time, because "reading" does not conflict;
  3. Then, thread C modifies the table field. At this time, because the transaction of thread A has not been submitted, that is, the MDL read lock is still occupied. At this time, thread C cannot apply for the MDL write lock and will be blocked.
  4. Then after thread C is blocked, subsequent select statements for the table will be blocked. If there are a large number of requests for the select statement of the table at this time, a large number of threads will be blocked. At this time, the threads of the database It will fill up quickly.

This is because the operation of applying for an MDL lock will form a queue, and the priority of obtaining a write lock in the queue is higher than that of a read lock. Once an MDL write lock wait occurs, all subsequent CRUD operations on the table will be blocked.

Shared lock: Multiple transactions are allowed to hold the lock at the same time, which is used to prevent other transactions from modifying the data when reading data. Shared locks will not block shared lock requests from other transactions, but will block exclusive and exclusive lock requests from other transactions.

Exclusive lock: Only one transaction is allowed to hold the lock, which is used to prevent other transactions from modifying the same data at the same time when modifying data. Exclusive locks block shared and exclusive lock requests from other transactions, but do not block exclusive lock requests from other transactions.

Exclusive lock: Only one transaction is allowed to hold the lock, which is used to prevent other transactions from modifying the same data at the same time when modifying data. Exclusive locks block all other transactional lock requests, including shared locks, exclusive locks, and exclusive locks.

The MDL is released after the transaction is committed, which means that the MDL is always held during the execution of the transaction .

  • operate

View the locking status of metadata locks

mysql> select object_type,object_schema,object_name,lock_type,lock_duration from performance_schema.metadata_locks;
+-------------+--------------------+----------------+--------------+---------------+
| object_type | object_schema      | object_name    | lock_type    | lock_duration |
+-------------+--------------------+----------------+--------------+---------------+
| TABLE       | MySQL_Advanced     | tb_user        | SHARED_READ  | TRANSACTION   |
| TABLE       | MySQL_Advanced     | tb_user        | SHARED_READ  | TRANSACTION   |
| TABLE       | MySQL_Advanced     | tb_user        | SHARED_WRITE | TRANSACTION   |
| TABLE       | MySQL_Advanced     | user_logs      | SHARED_WRITE | TRANSACTION   |
| TABLE       | performance_schema | metadata_locks | SHARED_READ  | TRANSACTION   |
+-------------+--------------------+----------------+--------------+---------------+
5 rows in set (0.00 sec)

3. Intention lock

  1. introduce

In order to avoid conflicts between added row locks and table locks when DML is executed, intention locks are introduced in the InnoDB engine, so that table locks do not need to check whether each row is locked.

If there is no intent lock, how does client 2 lock the table after the client has added a row lock to the table?

First, client 1 starts a transaction, and then executes DML operations. When executing DML statements, row locks are added to the rows involved.

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, add a table lock. At this time, it will check from the first row of data to the last row, improving efficiency lower.

With the intent lock, when performing DML operations, row locks will be added to the rows involved, and intent locks will also be added to the table.

When other clients lock the table, they can judge whether the lock can be successfully locked according to whether there is an intention lock.

  1. Classification
  • Intention shared lock: compatible with table lock shared lock, mutually exclusive with table lock exclusive lock
  • Intention exclusive lock: mutually exclusive with table lock exclusive lock and table lock shared lock

Intention shared locks and intention exclusive locks are table-level locks, which will not conflict with row-level shared locks and exclusive locks, and there will be no conflicts between intention locks, only with shared table locks ( lock tables ... read ) and exclusive table locks ( lock tables ... write ) conflict.

Once the transaction is committed, the intention shared lock and the intention exclusive lock will be released

To perform insert, update, and delete operations, you need to add an "intent exclusive lock" to the table first, and then add an exclusive lock to the record, so that you can quickly determine whether there are records in the table that are locked.

3. Row-level locks

Each operation locks the corresponding row data, the locking granularity is the smallest, the probability of lock conflicts is the lowest, and the concurrency is the highest. It is applied in the InnoDB engine

Three major differences between InnoDB engine and MySlAM engine: transactional foreign key row lock

For row-level locks, there are three main categories:

  1. Row lock (Record Lock): A lock that locks a single row record, preventing other transactions from updating and deleting this row. It is supported under both RC and RR isolation levels.

The following two types of row locks are implemented in InnoDB:

  • Shared lock (S): Allows a transaction to read a row, preventing other transactions from obtaining an exclusive lock on the same data set
  • Exclusive lock (X): Allows transactions with exclusive locks to update data, preventing other transactions from obtaining shared and exclusive locks on the same data set.

The compatibility of the two row locks is as follows:

-- 会话 1
BEGIN;
SELECT * FROM orders WHERE id = 1 FOR UPDATE;
-- 对 id=1 的数据行进行修改
UPDATE orders SET amount = amount + 100 WHERE id = 1;
COMMIT;

-- 会话 2
BEGIN;
-- 因为会话 1 对 id=1 的数据行进行了行锁,所以会话 2 不能同时对该行进行修改,
-- 如果执行下面的语句会一直等待会话 1 的事务提交或回滚
UPDATE orders SET amount = amount - 50 WHERE id = 1;
  1. gap lock

Gap lock: refers to locking the "gap" in an index range to prevent other transactions from inserting new data in this range. Gap locks are used to solve the phantom read problem.

For example, if a range query is executed in a certain transaction, and then new data is inserted in the gap in the range, then the same query is executed again, and some rows appear twice, which is a phantom read. Through the gap lock, other transactions can be prevented from inserting new data, thereby avoiding phantom reading.

Assume that there is a gap lock with a range id of (3, 5) in the table, then other transactions cannot insert the record with id = 4, which effectively prevents the occurrence of phantom reads.

-- 会话 1
BEGIN;
-- 对 id 大于 1 小于 10 的范围进行间隙锁定
SELECT * FROM orders WHERE id > 1 AND id < 10 FOR UPDATE;
-- 间隙锁会阻止其他事务在 id 大于 1 小于 10 的范围内插入数据,
-- 但允许其他事务在该范围之外的位置插入数据
COMMIT;

-- 会话 2
BEGIN;
-- 因为会话 1 对 id 大于 1 小于 10 的范围进行了间隙锁定,所以会话 2 不能在该范围内插入数据,
-- 如果执行下面的语句会一直等待会话 1 的事务提交或回滚
INSERT INTO orders (id, amount) VALUES (5, 500);
  1. Pro key lock

The difference between a key lock and a gap lock is that what he locks is not just a range, but also the lock record itself.

  • In the equivalent query on the index (non-unique ordinary index), when the last value does not meet the query requirements when traversing to the right, the key lock degenerates into a gap lock.

Assume that there is a next-key lock with the range id (3, 5] in the table, then other transactions can neither insert the record with id = 4 nor modify the record with id = 5.

Therefore, the key lock can not only protect the record, but also prevent other transactions from inserting new records into the gap in front of the protected record.

The mutual exclusion relationship between X and S locks between adjacent key locks also follows the mutual exclusion relationship between row locks.

  • Summarize:

In InnoDB, by default the transaction isolation level is implemented using row locks. When you need to lock an entire table, you can use table locks; when you need to solve the problem of phantom reading, you can use gap locks. When using gap locks, you need to pay attention to the scope of the lock to avoid affecting the normal operation of other transactions.

Guess you like

Origin blog.csdn.net/m0_56361048/article/details/131073620