In today's Internet, you cannot develop a large-scale multi-player APP without a database. How to ensure that everyone can read and write with high concurrency has always been a difficult architectural problem. First of all, high concurrency is eliminated, and the most commonly used method to ensure consistent reading and writing is transaction, and the key point of implementing a transaction is locking. mechanism.
Today we will introduce the principle and implementation of how the InnoDB storage engine implements the lock mechanism under high concurrency to meet consistent reading and writing.
Lock
The locking mechanism of the database is a key feature that distinguishes it from the file system. Used to manage concurrent access to shared resources. InnoDB uses locking mechanisms in many places, such as operating data tables, LRU page lists, and data rows in the buffer pool. In order to ensure consistency and integrity, a locking mechanism is required.
For different databases, the design and implementation of the lock mechanism are completely different:
● MyISAM engine: Table lock design, concurrent reading is no problem, but concurrent writing performance is poor.
●Microsoft SQL Server: Supports optimistic concurrency and pessimistic concurrency. Optimistic concurrency supports row-level locks. Maintaining locks is expensive. When the number of row locks exceeds the threshold, it will be upgraded to table locks.
●InnoDB engine: supports row locks and provides consistent non-locking reads. Row locks have no additional overhead and no performance degradation.
●Oracle: Very similar to the InnoDB engine.
Two types of locks: lock and latch
In the database, both lock and latch can be called locks, but there is a big difference.
Latch is generally called a latch, which is used to ensure the correctness of critical resource operations by concurrent threads. The object is a memory data structure. The lock time is required to be very short and deadlock will not be detected. In the InnoDB engine, it is divided into mutex (mutex) and rwlock (read-write lock).
Lock is used to lock objects in the database, such as tables, pages, and rows. The target is a transaction. It is released after commit/rollback and deadlock will be detected. Divided into row locks, table locks, and intent locks.
The locks we have below refer to lock type locks.
Four lock types
InnoDB supports four locks:
● Shared lock (S Lock): allows transactions Read a row of data
●Exclusive lock (X Lock): Allows a transaction to delete or update a row of data
●Intention S Lock: A transaction wants to obtain certain rows in a table Shared lock
●Intention X Lock: The transaction wants to obtain the exclusive lock of certain rows in a table
When transaction T1 acquires the shared lock of row The row data will not be changed, so transaction T2 can also directly obtain the shared lock of row r, which is called lock compatible.
When transaction T3 wants to obtain the exclusive lock of row r to modify data, it needs to wait for T1/T2 to release the row shared lock. This is called lock incompatibility.
S locks and X locks are both row locks, while IS locks and IX locks are intention locks and belong to table locks. Intention locks are designed to reveal the type of lock that will be requested for the next row within a transaction, that is, to lock at the finer granularity of a table lock. Since InnoDB supports table locks, intent locks will not block any requests except full table scans.
Lock compatibility:
IX | S | X | ||
Compatible | Compatible | Compatible | Not Compatible | |
Compatible | Compatible | Incompatible | Incompatible | |
Compatible | Not compatible | Compatible | Not compatible | |
Incompatible | Incompatible | Incompatible | Incompatible |
Storage Three tables of transaction and lock information
We can view the information of the current lock request in the transaction section through theshow engine innodb status command.
INNODB_TRX
| ||
---|---|---|
The unique transaction ID within the InnoDB storage engine | ||
The status of the current transaction | ||
The start time of the transaction | ||
The lock IDC waiting for the transaction, when the status is not LOCK WAIT, it is NULL | ||
The time the transaction waits to start | ||
The weight of the transaction reflects the number of rows modified and locked by a transaction. When rollback is required, select the transaction with the smallest value for rollback | ||
The thread ID of MySQL, the result displayed by show processlist | ||
SQL statement for transaction operation |
INNODB_LOCKS | |
---|---|
lock_id | lockID |
lock_trx_id | Transaction ID |
lock_mode | Lock mode |
lock_type | Type of lock, table lock or row lock |
lock_table | Table to be locked |
lock_index | Locked index |
lock_space | Space id of the lock object |
lock_page | The number of transaction-locked pages, NULL when the table is locked |
lock_rec | The number of transaction-locked rows, NULL when the table is locked |
lock_data | The primary key value of the transaction lock record, which is NULL when the table is locked |
# #INNODB_LOCK_WAITS
| |
---|---|
Transaction ID for applying for lock resources | |
Apply The ID of the lock | |
The blocking transaction ID | |
The blocking lock ID |
we can see all transactions, whether the transaction is blocked, and what is the blocked lock ID. Afterwards, view all lock information through
INNODB_LOCKS
. After that, you can view the waiting information and blocking relationship of the lock through
INNODB_LOCK_WAITS
. Through these three tables, you can view the transaction and lock status more clearly, and you can also perform joint queries. In the following scenarios, we will show the contents of these three tables.
Isolation levelFirst of all, let’s talk about the four transaction isolation levels of the database:
● READ UNCOMMITTED (0 ): Browsing access level, there are dirty reads, non-repeatable reads, and phantom reads
● READ COMMITTED (1): Cursor stability level, there are non-repeatable reads and phantom reads
● REPEATABLE READ( 2): There is phantom reading
● SERIALIZABLE (3): Isolation level, ensuring transaction security, but completely serial and low performance
These four transaction isolation levels are specified by the SQL standard. The default isolation level of InnoDB is REAPEATABLE READ, but unlike other databases, it also uses the Next-Key-Lock lock algorithm, which can avoid the occurrence of phantom reads, so it can fully meet the transaction isolation requirements, that is, it can achieve SERIALIZABLE Isolation level.
The lower the isolation level, the fewer locks requested by the transaction or the shorter the lock holding time, so the default isolation level of most databases is READ COMMITED. However, relevant analysis also points out that the performance overhead of isolation levels is almost the same, so users do not need to adjust the isolation level to improve performance.
Commands to view and modify the transaction isolation level:
mysql> select @@session.tx_isolation; +------------------------+ | @@session.tx_isolation | +------------------------+ | REPEATABLE-READ | +------------------------+ 1 row in set (0.00 sec) mysql> set session transaction isolation level SERIALIZABLE; Query OK, 0 rows affected (0.00 sec)
In the example, the transaction isolation level of this session is modified. If you need to modify the global parameters, you can replace session with global. If you want to make permanent changes, you need to modify the configuration file:
[mysqld] transaction-isolation = READ-COMMITED
At the transaction isolation level of SERIALIZABLE, InnoDB will automatically add LOCK IN SHARE MODE after each SELECT statement to add a shared lock to the read operation. , so consistent non-locking reads are no longer supported.
Since InnoDB can reach SERIALIZABLE at the REPEATABLE READ isolation level, it is generally not necessary to use the highest isolation level.
Consistent non-locking read and multi-version concurrency control Consistent non-locking read (consistent non-locking read) refers to InnoDB’s multi-row Version control (Multi Version Concurrency Control, MVCC) method to read the row data in the database at the current execution time.
That is, if the read row is undergoing a change operation, the read will not wait for the release of the row lock, but will read a snapshot data of the row. A snapshot refers to a historical data of the row, which is completed through the undo operation. This method greatly improves the concurrency of the database, which is also the default setting of InnoDB.
A snapshot is a historical version of the current row, but there may be multiple versions. The row data has multiple snapshot data. This technology becomes row multi-version technology, and the resulting concurrency control is called multi-snapshot. Version Concurrency Control (MVCC). InnoDB uses non-locking consistent reads in the READ COMMITED and REPEATABLE READ isolation levels, but the quick data definitions used in these two isolation levels are different:
● READ COMMITED: always read The latest snapshot
● REPEATABLE READ: Always read the row data version at the beginning of the transaction
We execute an example:
|
||
---|---|---|
Session A | Session B | |
BEGIN | ||
select * from z where a = 3; | ||
##BEGIN |
4 | |
update z set b=2 where a=3; |
5 | |
##6 |
||
##COMMIT; | select * from z where a = 3; | |
##8 |
COMMIT; |
|
The above is the detailed content of MySQL locks and transaction isolation levels (introduction). For more information, please follow other related articles on the PHP Chinese website!