** MySQL locking mechanism and usage analysis **

Original: https://www.jb51.net/article/139113.htm

MySQL locking mechanism is relatively simple, its most notable feature is the different storage engines support different lock mechanisms. For example, MyISAM, and MEMORY storage engine uses a table-level locking; BDB storage engine uses page locks, but also supports table-level locking; InnoDB storage engine supports both row-level locking, and also supports table-level locking, but by default uses row-level locking.

MySQL lock these three characteristics may be roughly summarized as follows:

(1) table-level lock : Small overhead, lock fast; not deadlock; lock large size, the probability of lock conflicts of the highest and lowest degree of concurrency.

(2) row-level locking : large overhead, locking slow; there will be a deadlock; locking granularity minimum, the minimum probability of lock conflicts, have the highest degree of concurrency.

(3) page locks : lock overhead and time boundaries between the table and row locks; deadlock occurs; boundary between the lock granularity and row locks the table, the general concurrency.

Only from the perspective of the lock, table lock is more adapted to query-based, only a few are applied in the condition updating the index data, such as Web applications; and row-level locks are more suitable for a large number of concurrent update conditions by the small number of different index application data, and also that of concurrent queries, such as some online transaction processing systems.

 

A, MyISAM table locks

1. Query table-level lock contention

show status like 'table%';

If the value of table_locks_waited is relatively high, then there is a more serious table-level lock contention.

2. MySQL table-level locking lock mode

MySQL table-level locking has two modes: a shared table read locks and exclusive write locks table.

When a session for a table plus a read lock after the session can only access the locked table, but can only be read; other session can be read on this table, but the write operation will be blocked, need waiting to release the lock. When a session for a table plus a write lock after locking the session can only access this table, you can read and write, read and write the other session table operation will be blocked, need to wait for the lock freed.

Between the read operation and write operation MyISAM tables, as well as between the write operation is serial.

3. How to add table lock

Plus a read lock:

lock table tbl_name read;

Write-lock:

lock table tbl_name write;

Release the lock:

unlock tables;

MyISAM before executing the query, will be automatically added to all table read locks involved , before performing the update operation, will be automatically added to the table write locks involved , this process does not require user intervention , so that users generally do not need to directly use lOCK tABLE commands to explicit lock MyISAM table. MyISAM table to explicit lock, typically to a certain extent, the analog transaction operations, to achieve a consistent point in time of reading the plurality of tables.

Note that when using LOCK TABLES, not only need to lock all the tables once used, but also, how many times the same table appears in the SQL statement, it is necessary by the same SQL statement alias locked many times, otherwise it will be wrong!

4. concurrent insert

MyISAM storage engine has a variable concurrent_insert system, specifically to control the behavior of concurrent insert, and its value may be 0, 1 or 2.

(1) When set to 0 concurrent_insert, not allow concurrent insertion.

(2) is set to 1 when concurrent_insert, MyISAM tables if no voids (i.e., the middle of the table rows are not deleted), while allowing a MyISAM table reading process, another process is inserted from the end of the table records. This is the MySQL default settings.

(3) When the concurrent_insert set to 2, whether there is no empty MyISAM table, allow concurrent inserts in the trailer record.

Just add "local" add option table lock command, namely: lock table tbl_name local read, in a case where concurrent insert MyISAM table satisfies the conditions, other users can concurrently record inserted end of the table, the update operation will be blocked and locked users can not access other users to concurrently insert records.

5. MyISAM lock scheduling

When the process of writing and reading processes simultaneously request the same MyISAM table write locks and read locks, write process will give priority to get the lock. Not only that, even if the first-read lock request queue, the request to write, write lock before the read lock requests will be inserted! This is because MySQL write requests are generally considered more important than the read request. This is exactly the MyISAM table is not suitable for a lot of reasons for the update operation and query applications, because a large number of update operations can cause query operation is difficult to obtain a read lock, which may never be blocked.

Adjust the scheduling behavior of MyISAM by what some settings:

(1) by specifying boot parameters low-priority-updates, given that the default MyISAM engine as claimed priority to read requests.

(2) by executing the command SET LOW_PRIORITY_UPDATES=1, the update to the connection requests issued by lower priority.

(3) by specifying the INSERT, UPDATE, LOW_PRIORITY DELETE statement properties, lowers the priority of the statement.

(4) max_write_lock_count set an appropriate value to the system parameters, when a read lock table to achieve this value, MySQL will write a request to temporarily lower the priority, the chance to read a certain process to acquire a lock.

 

 

Two, InnoDB lock problem

1. Query InnoDB row lock contention

show status like 'innodb_row_lock%';

If the value InnoDB_row_lock_waits and InnoDB_row_lock_time_avg relatively high, indicating serious lock contention, then can be further observed that the occurrence of a table lock conflicts, and the like by setting the data line InnoDB Monitors, and analyze the causes lock contention.

Turn on the monitor:

CREATE TABLE innodb_monitor(a INT) ENGINE=INNODB;
Show innodb status\G;

Stop Monitor:

DROP TABLE innodb_monitor;

After Turn on the monitor, by default it will be recorded every 15 seconds to log content monitoring, and if prolonged will lead to open .err files become very large, so the user after confirming the cause of the problem, remember to delete the monitoring tables to close monitor , or to start the server by using the "--console" option to turn off write log files.

2. InnoDB row locks and locking method

There are two types of InnoDB row lock: shared lock (S) and exclusive lock (X). In order to allow the coexistence of table locks and row locks, multi-granularity locking mechanism, InnoDB there are two kinds of intent locks for internal use: intent shared locks and exclusive locks intent, both intent locks are table locks. A transaction must obtain intent lock correspondence table corresponding to the data line before the lock . Intent locks InnoDB is added automatically, without user intervention. For UPDATE, DELETE and INSERT statements, InnoDB will automatically give involves collection of data plus exclusive lock (X-) ; ordinary SELECT statement, InnoDB not add any lock; transaction explicitly to the recording current shared locks or rows by the following statement locks .

Key: update, delete, insert, will automatically lock. Query does not automatically lock (shared locks). In fact, the JVM lock is to prevent concurrent queries against the database of the chant?

Set autocommit=0;

Shared lock (S):

SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE

Exclusive lock (X):

SELECT * FROM table_name WHERE ... FOR UPDATE

Release the lock:

unlock tables;

(Implicitly commit the transaction)

When a transaction to get a table shared lock, other transactions can query the records of the table, you can also add a shared lock on the record. When a transaction to update the operating table, if there is another transaction are added to the table shared lock, you need to wait to release the lock, if another transaction also perform an update operation on the table, it will lead to a deadlock another transaction is aborted, the current transaction to complete the update operation. When a transaction to get a table exclusive lock, other transactions can query the log table can not be shared locks can not update the record, there will be waiting.

3. InnoDB row lock implementations

InnoDB row lock is achieved through the lock on the index entry to the index, InnoDB row lock to achieve this characteristic means that:

(1) Only through index conditions to retrieve the data, InnoDB only row-level locking. Otherwise, InnoDB uses a table lock.

(2) Because MySQL row locks are locks for the index plus, not a plus for the record lock, so although access is recorded in different rows, but if you use the same index key, there will be lock conflicts.

(3) 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. (Although using a different index, but if the record is already locked by another session then it is to wait.)

(4) Even with the index field in the condition, but whether to use the index to retrieve the data by MySQL determined by determining the cost of various 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.

4. Lock gap

When retrieving data using the range condition, the recording range of conditions, but the key does not exist, InnoDB will be locked, the lock is called "lock space." InnoDB object using the gap locks, on the one hand to prevent phantom read, on the other hand to meet the needs of recovery and replication. But this will block the locking mechanism in line with key values ​​within the range of conditions concurrent inserts, causing serious lock wait, so you should try to avoid using the range of conditions to retrieve the data.

Except when locked by the locking gap outside the range condition, if a condition equal to the recording request a lock does not exist, InnoDB will lock using a gap!

Effect on InnoDB lock mechanism 5. The recovery and replication needs

MySQL successfully executed by BINLOG record INSERT, UPDATE, DELETE SQL statements such as update data, and thereby achieving recovery and the main MySQL database from replication. MySQL recovery mechanism (actually a copy Slave Mysql continue to do in the recovery BINLOG based) has the following characteristics:

(1) MySQL Recovery is the SQL statement level, that is, to re-execute the SQL statement BINLOG.

(2) MySQL Binlog is in the order of committed transactions recorded restore this order is carried out.

So MySQL recovery and replication requirements of the lock mechanism is: before a transaction is not committed, other concurrent transactions can not insert any records that meet the conditions of the lock, which is not allowed phantom reads.

Additionally, for the average of the select statement, MySQL uses multiple versions of data consistency, you do not need to add any lock, however, for the " insert into target_tab select * from source_tab where ..." and " create table new_tab ...select ... From source_tab where ..." This SQL statement, the user does not do any update on source_tab, but for MySQL this SQL statements to do a special deal, plus a shared lock to source_tab. This is because, not locked, and if during this SQL statement is executed, there is another transaction of source_tab been updated and were first submitted, then BINLOG, the update operation will position before the SQL statement, use this BINLOG database recovery, the result would be inconsistent with the recovery of the actual application logic, replication can lead to inconsistency from the master database. Because the application is actually insert data target_tab or new_tab is the data before another transaction to source_tab update, and BINLOG record is updated first and then perform select ... insert ... statement. If the SELECT statement that the above range condition, InnoDB gap will add to the source table lock. So this SQL statement will block concurrent updates to the original table, should be avoided.

6. InnoDB table lock case use and precautions

For InnoDB tables, in most cases you should use row-level locking, but in individual special affairs, may also consider the use of table-level locking, mainly in the following two situations:

(1) the transaction needs to be updated most or all of the data table and relatively large, if the default row locks, this transaction is not only low efficiency, and may cause other transactions to wait long locks and lock the conflict, in this case can be considered use table locks to increase the speed of execution of the transaction.

(2) a transaction involving multiple tables, more complex, is likely to lead to deadlock, resulting in a large number of transaction rollback. This situation can also be considered a one-time transaction involves locking the table in order to avoid deadlock and reduce the overhead of database due to transaction rollback brings.

In addition, the use of table locks in InnoDB needs to note the following points:

(1) Although it is possible to use LOCK TABLES add InnoDB table lock, but not by a table lock InnoDB storage engine management layer, but by a layer ──MySQL Server responsible only when autocommit = 0, innodb_table_locks = 1 when (the default setting), plus MySQL InnoDB layer in order to know the table lock, MySQL Server also add to the perception of InnoDB row lock, in this case, in order to automatically identify a deadlock involving InnoDB table-level locking; otherwise, InnoDB will not automatically this deadlock detection and treatment.

(2) to be careful when using LOCK TABLES on InnoDB table lock, 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 commit the transaction; COMMIT or ROLLBACK does not release with lOCK tABLES plus table-level locks, table locks must be released with the UNLOCK tABLES.

7. About Deadlock

MyISAM table locking is deadlock free, this is because once MyISAM always get all the locks required to meet either all, or wait, so there is no deadlock. But in InnoDB, in addition to a single SQL transaction consisting of the lock is gradually obtained, which determines the deadlock occurs in InnoDB is possible.

After a deadlock occurs, InnoDB can usually be detected automatically, and release the lock and a transaction rollback, another transaction to acquire a lock, continue to complete the transaction. However, in the context of an external lock, or table involving lock, InnoDB not completely automatically detect deadlocks, timeout parameters that need to wait innodb_lock_wait_timeout solved by setting lock.

Generally speaking, the deadlock is designed for application by adjusting business processes, SQL statements, database objects, design, transaction size, as well as access to the database, the vast majority of the deadlock can be avoided. Here to introduce several common methods avoid deadlock by way of example.

(1) in the application, if a different program concurrent accesses a plurality of tables, the same should be agreed in order to access the table, which can greatly reduce the chance of deadlock.

(2) when the program processing data in a batch fashion, if the pre-sort the data, ensure that each thread according to a fixed sequence to the recording process, it can significantly reduce the possibility of deadlock.

(3) in the transaction, if you want to update the records, should directly apply a sufficient level of locks, namely exclusive lock, and not to apply for a shared lock, and then apply for discharge of updates locks, because when the user applies an exclusive lock, other transactions may and they have received the same record shared lock, resulting in lock conflicts, and even deadlock.

(4) In REPEATABLE-READ isolation level, if two threads simultaneously recording the same conditions using SELECT ... FOR UPDATE plus exclusive lock, in the absence of compliance with the conditions under which records case, two threads will lock success. 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.

(5) When the isolation level is READ COMMITTED, if two threads to execute SELECT ... FOR UPDATE, to determine whether the conditions exist for the record, if not, insert records. At this time, only one thread can be inserted success, another thread will lock wait, when the first one thread is submitted, the second thread because the primary key re wrong, but although this thread is wrong, but it will get an exclusive lock! Then if there is a third thread again apply for an exclusive lock, there will be a deadlock. In this case, you can directly do insert, and then re-capture the primary key exception, or in the event of heavy primary key error, always perform row ROLLBACK obtained his release lock

More on MySQL-related content and interested readers can view the site topic: " MySQL database locking techniques to gather relevant ", " MySQL Stored Procedures skills Daquan ", " MySQL commonly used functions Summary large ", " MySQL log operating skills Daquan " and " MySQL transaction handling tips summary "

In this paper, we hope that the MySQL database meter help.

 

Optimistic lock:

update user set money = 100.00 where id=1 and version=1;

The wording lock thrown database should be processed in the code money + 100.00, locking the JVM layer

update user set money = money+100.00 where id = 1;

Guess you like

Origin www.cnblogs.com/cuiqq/p/12275488.html