MySQL MyISAM and table locks

MySQL MyISAM and table locks

 

In the database, in addition to the contention of CPU, memory, IO, etc., data is also a resource shared by many users. How to ensure the consistency and validity of data concurrency is a problem that must be solved in all databases. Lock conflicts also affect the database. An important factor in concurrency performance. The locking mechanism between different storage engines in MySQL is not necessarily the same. For example, MyISAM and MEMORY use table locks, BDB uses page locks, but wild supports table locks. InnoDB defaults to row locks, but also supports table locks.

 

There are generally three types of MySQL locks:

  1. Table lock: low overhead, fast locking; no deadlock; large lock granularity, high probability of lock conflict, and lowest concurrency
  2. Row lock: high overhead, slow locking; deadlock occurs; small lock granularity, low probability of lock conflict, and highest concurrency
  3. Page locks: overhead and locking time are between table locks and row locks; deadlocks will occur, and lock granularity is between table locks and row locks

 Only from the perspective of locks, table locks are used for applications that mainly query and update data according to index conditions, such as WEB applications; while row-level locks are more suitable for a large number of concurrent updates of a small amount of different data according to index conditions. There are also concurrent query applications, such as some online transaction processing (OLTP) systems.

 

MyISAM table lock

MyISAM only supports table locks, which are the only locks supported by early MySQL. With the continuous improvement of the application's requirements for transaction integrity and concurrency, MySQL began to develop a transaction-based storage engine. Later, InnoDB, which supports page locks, BDB, and row locks, gradually appeared.

 

Table locks have two modes: shared read locks and exclusive write locks. Read locks are compatible with read locks, read locks and write locks are mutually exclusive, and write locks and write locks are mutually exclusive. That is to say, the read operation of one connection of the MyISAM table will not block the read operation of other connections, but it will block the write operation of other connections, and the write operation of one connection will block the read operation and write operation of other connections.

 

MyISAM will automatically add a read lock to the involved table when executing a query (SELECT), and automatically add a write lock to the involved table when executing an update (UPDATE, DELETE, INSERT), etc. But we can also display locked/unlocked:

 

LOCK TABLES
    tbl_name [[AS] alias] lock_type
    [, tbl_name [[AS] alias] lock_type] ...

lock_type:
    READ [LOCAL]
  | [LOW_PRIORITY] WRITE

UNLOCK TABLES

 The LOCAL keyword is used to indicate that concurrent inserts are allowed, as will be discussed later

 

The following demonstrates some case locking situations:

 read blocking write


 

The following black background color is session A, and the gray background color is session B

 

Session A adds a read lock to the user. After the lock, session A can query, but cannot insert

Session B can query, but inserts block:


 

After session A releases the lock, session B is inserted successfully:



 

Only locked tables can be accessed

After the table is locked, only the locked table can be accessed, and the unlocked table cannot be accessed:

 


 



 

All aliases used must be locked once

 When using an alias, the alias must also be locked, and even if it is the same table, if the alias is different, another lock is required:



 

 

concurrent insert

The reading and writing of MyISAM tables are serial, but under certain conditions, MyISAM tables also support concurrent execution of queries and insertions. or NEVER), 1 (or AUTO) and 2 (or ALWAYS), when concurrent_insert is 0, concurrent inserts are not allowed, when concurrent_insert is 1 if there are no holes in the table (that is, there are no deleted rows in the middle of the table), then Allows one session to read the table while another table inserts records at the end of the table, which is the default value; when concurrent_insert is 2, allows concurrent insertion of records at the end of the table.

 

Next, we will demonstrate the effects of these three modes.

 Set concurrent_insert to 0:


 Session A locks the user table (note that the LOCAL keyword must be added here),

 you can see that the insertion of session B will block:

 

Set concurrent_insert to 1, session A adds a read lock to the user,


 Session B can still be inserted, because the table has no space fragmentation at this time (you can use optimize table table_name to defragment)

After deleting some data (creating fragmentation), lock it again:

At this point, session B tries to insert data again, and you can see that it will be blocked:


 

Set concurrent_insert to 2, and session A adds a read lock to the user:


 Session B can insert data at:

 

If your application uses MyISAM tables, and you want to have a certain amount of insert concurrency, then you can set concurrent_insert to 2, and periodically execute OPTIMIZE TABLE to defragment during idle periods.

 

It is also worth noting that when a session A requests a read lock on a MyISAM table, and another session B also requests a write lock on the same table, MySQL will let session B acquire a write lock, even if the lock waits for the read request in the queue first After the write request arrives, MySQL will also insert the write request before the read request. This is also the reason why MyISAM tables are not suitable for applications with a large number of update operations and query operations. A large number of update operations will make it difficult for early query operations to obtain locks and may block for a long time. For this, we can make some settings to break this rule:

  1. By starting the parameter low-priority-updates, the MyISAM engine defaults to giving read requests a higher priority
  2. Make all update requests made by the current connection lower priority by setting low-priority-updates=1
  3. INSERT, UPDATE, DELETE statements all have a LOW_PRIORITY attribute, through which the priority of the statement is reduced, such as insert low_priority into user values ​​...

 

 Reference: http://dev.mysql.com/doc/refman/5.7/en/lock-tables.html

In-depth MySQL

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326425529&siteId=291194637