Five minutes to understand Mysql row-level locking - "get to the bottom Mysql lock" (turn)

We first need to know a major premise is: mysql lock is a specific storage engine to achieve. So like the default engine MyISAM and InnoDB engine of third-party plug lock Mysql implementation mechanism is different.
Mysql There are three levels of locking: table-level locks, page-level locking, row-level locking

First, the definition


  • Each time the lock is a row of data locking mechanism is the row-level locking (row-level). Row-level locking is not locked MySQL own manner, but by other storage engines themselves implemented

Second, the advantages and disadvantages


1. Advantages

  • Due to the small size lock contention rate, high concurrency.

2. shortcomings

  • Implement complex, large overhead.
  • Locking slow, prone to deadlock

Third, support a storage engine


  • Use row-level locking of the main InnoDB storage engine, and MySQL distributed storage engine NDBCluster

Fourth, row-level locking type


InnoDB's row-level locking is also divided into two types: shared locks and exclusive locks , and in the locking mechanism of the implementation process in order to allow row-level locking and table-level locking coexist , InnoDB also uses intent locks (table-level locking) of concept, and we will have a shared intent locks and intent exclusive lock both.

The Role of Intention lock is when a transaction needs to lock access to resources, and the resources they need if they have been occupied when the exclusive lock, the transaction may need to add a suitable locking intent locks rows in the table above. If they need a shared lock, then add a table top in intent shared lock . And if they need is a line (or some rows) added on top of an exclusive lock, then the first to add a table top in intent exclusive lock .

Intent shared lock can coexist more, but intent exclusive lock while only one exists. So, we can say the InnoDB 锁定模式实际上可以分为四种: 共享锁(S), 排他锁(X), 意向共享锁(IS) and意向排他锁(IX)

Lock Compatibility Mode:
Write pictures described here

Fifth, row-level locking implementation


InnoDB row lock on the index is by giving 索引项加锁to achieve. Therefore, only through index conditions to retrieve the data, InnoDB only row-level locking. Otherwise, InnoDB uses a table lock. Other considerations:

  • When not queries through index conditions, InnoDB table lock is used, instead of row locks.
  • Because MySQL row locks are locks for the index plus, not a plus for the record lock, so even record access different rows, if you use the same index key, there will also lock the conflict.
  • When the table has a plurality of indexes, different transactions can lock with different index different rows, additionally, whether used primary key index, the general index or a unique index, InnoDB row locks are used to lock the data.
  • Even with the condition in the index field, but whether to use the index to retrieve specific data is determined by the cost of MySQL by a different judge of the implementation plan, if MySQL full table scan think higher efficiency, such as some small tables, it will not use the index, in this case the use InnoDB table locks instead of row locks. Therefore, when analyzing locking conflicts, do not forget to check the SQL execution plan to verify the real use of the index.

Implicit lock :

  • InnoDB automatic lock intent.
  • For UPDATE, DELETE and INSERT statements, InnoDB automatically added to the set of data relates to 排他锁(X);
  • For ordinary SELECT statement, InnoDB will not add any locks;

Show Lock :

  • Shared lock (S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE
  • Exclusive lock (X):SELECT * FROM table_name WHERE ... FOR UPDATE

With SELECT ... IN SHARE MODE obtain a shared lock, mainly used in data dependencies needed to confirm a row record exists, and to ensure that no one on this record UPDATE or DELETE operations.

However, if the current transaction also requires the record to be updated operation, it is likely to cause a deadlock, after locking rows for applications that require an update operation, you should use SELECT ... FOR UPDATE way to get an exclusive lock.

How to add InnoDB table lock :

When using LOCK TABLES on InnoDB table lock should pay attention to, to AUTOCOMMIT is set to 0, otherwise it will not give MySQL table lock; before the end of the transaction, do not use the UNLOCK TABLES unlock the tables, because UNLOCK TABLES implicitly commits the transaction ; COMMIT, or ROLLBACK and can not be released by adding lOCK tABLES table lock, the lock must be released by the table UNLOCK tABLES.

SET AUTOCOMMIT=0;
LOCK TABLES t1 WRITE, t2 READ, ...;
[do something with tables t1 and t2 here];
COMMIT;
UNLOCK TABLES;
  
  
  • 1
  • 2
  • 3
  • 4
  • 5

Since they lock the table, how MyISAM engine does not choose it!

Six, locking gap (Next-Key Lock)


1. Lock justice gap:

Innodb by locking rules prior to the first index key lock to the data recorded mark information on spatial and space after the last key index achieved. This Innodb lock implementation is known as "the NEXT-KEY locking" ( 间隙锁), since looking through the scope Query execution in the case, it will lock all the key indexes within the entire range, even if the key does not exist.

Example: If the emp table only records 101, which are empid values ​​1,2, ..., 100, 101, the following SQL:

mysql> select * from emp where empid > 100 for update;
  
  
  • 1

Is a range of retrieval condition, InnoDB will not only meet the criteria value recording empid lock 101, also of greater than 101 empid (these records do not exist) in the "gap" lock.

2. The gap lock disadvantages:

  • Gap locks have a more fatal weakness, that is, when a range of key lock, even if there is not some innocent keys will be locked, and any data within the range of key values ​​can not be inserted into the lock when the lock. In some scenarios that might cause great harm performance
  • When Query can not use the index, Innodb will renounce the use of row-level locking and switch to table-level locking, resulting in reduced concurrency performance;
  • When the index does not contain Quuery use all of the filters, the index data retrieval key points to a part of the data may not be part of the result set Query ranks, but will be locked, since the gap of locks is a range, rather than a specific index key;
  • When Query When using the index location data, if the index key using the same data but a different row access time (index only part of the filter conditions), as will be locked

3. gap lock action:

  • Prevent phantom read, isolation level to meet the relevant requirements.
  • In order to restore data and need to be replicated.

4. Note

  • In the development of practical applications, especially in concurrent insert relatively large number of applications, we should try to optimize the business logic, try to use equal conditions to access updated data, avoiding the use of range conditions.
  • InnoDB locks when the gap except by the scope of the conditions outside the lock, if the conditions are equal to the recording request a lock does not exist, a gap is also used InnoDB lock.

Seven, see row-level lock contention


Execute SQL:mysql> show status like 'InnoDB_row_lock%';

mysql> show status like 'InnoDB_row_lock%';
+-------------------------------+-------+
| Variable_name                 | Value |
+-------------------------------+-------+
| InnoDB_row_lock_current_waits | 0     |
| InnoDB_row_lock_time          | 0     |
| InnoDB_row_lock_time_avg      | 0     |
| InnoDB_row_lock_time_max      | 0     |
| InnoDB_row_lock_waits         | 0     |
+-------------------------------+-------+
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

If you find more serious lock contention, it can also lock conflicts occur further observation tables, rows, etc. by setting the InnoDB Monitors, and analyze the causes lock contention. Such as:

Set Monitor: mysql> create table InnoDB_monitor(a INT) engine=InnoDB;

Views: mysql> show engine InnoDB status;

Stop View: mysql> drop table InnoDB_monitor;

Specific reference: InnoDB Monitor

Eight deadlock


What is a deadlock : you wait for me to release the lock, I'll wait for you to release the lock will form a deadlock.

How to find a deadlock : the InnoDB transaction management and locking mechanisms, there is a special mechanism to detect deadlocks, will have the presence of the deadlock after the deadlock in a very short time detected in the system

Solution :

  • The lesser of the transaction rollback
  • In REPEATABLE-READ isolation level, if two threads simultaneously recording the same conditions with SELECT ... FOR UPDATE plus exclusive lock, in the absence of compliance with the conditions under which records case, two threads will lock success. It finds record does not already exist, it tries to insert a new record, if two threads are doing, there will be a deadlock. In this case, change the isolation level READ COMMITTED, problems can be avoided.

Analyzing transaction size : each transaction insert, update or delete data amount

Note :

  • When the scene of deadlock involved more than InnoDB storage engine, InnoDB is no way to detect this deadlock, this time can only timeout limit parameter InnoDB_lock_wait_timeout by locking to resolve.

Nine, optimizing row-level locking


Because InnoDB storage engine to achieve a row-level locking, while locking mechanism in achieving the performance cost than table-level locking may will be higher, but in terms of overall concurrent processing capability is much better than MyISAM table level locked. When the system is higher when the amount of concurrency, InnoDB and MyISAM overall performance will have a clear advantage compared. However, the row-level locking InnoDB also has its weak side, when we used improperly, it may make InnoDB overall performance not only can not be higher than MyISAM, and may even be worse.

(1) To the rational use of InnoDB row-level locking, so avoid weaknesses, we must do the following:
A) as much as possible so that all data retrieval will be done through an index to avoid InnoDB because you can not lock and key by index upgraded to table-level locking;
b) the rational design of the index, so the index InnoDB lock key on top of the time as accurately as possible the narrow lock range, to avoid unnecessary locked affect the execution of other Query;
c) possible reducing the range of data retrieval based on filter conditions, avoid the negative influence of the gap to bring the lock should not locked locked records;
D) try to control the size of the transaction, the amount of resources to reduce the length of the lock and the locking time;
E) in a business environment Where permitted, as far as possible the use of lower transaction isolation levels, in order to reduce the additional costs because the realization of MySQL transaction isolation level brings.

(2) Due to InnoDB row-level locking and transactional, it would certainly produce a deadlock, the following tips are some of the more commonly used to reduce the probability of occurrence of the deadlock:
A) similar service module, to the extent possible in accordance with the same access sequence access to prevent deadlock;
b) in the same transaction, the lock as possible once all the resources needed to reduce the probability of deadlock;
c) for the part of the business is very prone to deadlock, you can try to upgrade the lock particle size, to reduce the probability of deadlock by locking the table level.

Original Address: https://blog.csdn.net/zcl_love_wx/article/details/81983267

Guess you like

Origin blog.csdn.net/qq_37598011/article/details/90341189