General talk about MySQL (4)

 4. MySQL lock mechanism

1- Overview of database lock theory

A lock is a mechanism by which a computer coordinates concurrent access to a resource by multiple processes or threads.

In the database, in addition to the contention of traditional computing resources (such as CPU, RAM, I/O, etc.), 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.

Analogy: Shopping online

For example, we go to Taobao to buy a product, and there is only one product in stock. If another person buys it at this time, how to solve the problem of whether you bought it or another person bought it?

Transactions must be used here. We first take out the item quantity from the inventory table, then insert the order, insert the payment table information after payment, and then update the item quantity. In this process, using locks can protect limited resources and solve the contradiction between isolation and concurrency.

Classification of locks

From the type of data operation (read\write)

  • Read lock (shared lock): For the same piece of data, multiple read operations can be performed simultaneously without affecting each other.
  • Write lock (exclusive lock): Before the current write operation is completed, it will block other write locks and read locks.

From the granularity of data operations

  • table lock
  • row lock

2- Read lock case explanation

Table lock (partial reading) MyISAM engine is used below.

Features: It favors the MyISAM storage engine, with low overhead and fast locking; no deadlock; large locking granularity, the highest probability of lock conflicts, and the lowest concurrency.

Create table SQL

<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql"><span style="color:#0000ff">create</span> <span style="color:#0000ff">table</span> mylock (
    id <span style="color:#a31515">int</span> <span style="color:#0000ff">not</span> <span style="color:#0000ff">null</span> <span style="color:#0000ff">primary</span> key auto_increment,
    name <span style="color:#a31515">varchar</span>(<span style="color:#880000">20</span>) <span style="color:#0000ff">default</span> <span style="color:#a31515">''</span>
) engine myisam; #注意这里使用了MyISAM引擎

<span style="color:#0000ff">insert</span> <span style="color:#0000ff">into</span> mylock(name) <span style="color:#0000ff">values</span>(<span style="color:#a31515">'a'</span>);
<span style="color:#0000ff">insert</span> <span style="color:#0000ff">into</span> mylock(name) <span style="color:#0000ff">values</span>(<span style="color:#a31515">'b'</span>);
<span style="color:#0000ff">insert</span> <span style="color:#0000ff">into</span> mylock(name) <span style="color:#0000ff">values</span>(<span style="color:#a31515">'c'</span>);
<span style="color:#0000ff">insert</span> <span style="color:#0000ff">into</span> mylock(name) <span style="color:#0000ff">values</span>(<span style="color:#a31515">'d'</span>);
<span style="color:#0000ff">insert</span> <span style="color:#0000ff">into</span> mylock(name) <span style="color:#0000ff">values</span>(<span style="color:#a31515">'e'</span>);

<span style="color:#0000ff">select</span> <span style="color:#ab5656">*</span> <span style="color:#0000ff">from</span> mylock;
</code></span></span>

operation result

<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">mysql<span style="color:#ab5656">></span> <span style="color:#0000ff">select</span> <span style="color:#ab5656">*</span> <span style="color:#0000ff">from</span> mylock;
<span style="color:#ab5656">+</span><span style="color:#008000">----+------+</span>
<span style="color:#ab5656">|</span> id <span style="color:#ab5656">|</span> name <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">----+------+</span>
<span style="color:#ab5656">|</span>  <span style="color:#880000">1</span> <span style="color:#ab5656">|</span> a    <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>  <span style="color:#880000">2</span> <span style="color:#ab5656">|</span> b    <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>  <span style="color:#880000">3</span> <span style="color:#ab5656">|</span> c    <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>  <span style="color:#880000">4</span> <span style="color:#ab5656">|</span> d    <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>  <span style="color:#880000">5</span> <span style="color:#ab5656">|</span> e    <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">----+------+</span>
<span style="color:#880000">5</span> <span style="color:#0000ff">rows</span> <span style="color:#0000ff">in</span> <span style="color:#0000ff">set</span> (<span style="color:#880000">0.00</span> sec)
</code></span></span>

①Add table lock manually

lock table table name read(write), table name 2 read(write), others;

  • read(write) means: whether to add a read lock or a write lock to this table;
<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">mysql<span style="color:#ab5656">></span> lock <span style="color:#0000ff">table</span> mylock read;Query OK, <span style="color:#880000">0</span> <span style="color:#0000ff">rows</span> affected (<span style="color:#880000">0.00</span> sec)
</code></span></span>

View the locks added to the table

<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">mysql<span style="color:#ab5656">></span> <span style="color:#0000ff">show</span> <span style="color:#0000ff">open</span> tables;
<span style="color:#ab5656">+</span><span style="color:#008000">--------------------+------------------------------------------------------+--------+-------------+</span>
<span style="color:#ab5656">|</span> Database           <span style="color:#ab5656">|</span> <span style="color:#0000ff">Table</span>                                                <span style="color:#ab5656">|</span> In_use <span style="color:#ab5656">|</span> Name_locked <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">--------------------+------------------------------------------------------+--------+-------------+</span>
<span style="color:#ab5656">|</span> performance_schema <span style="color:#ab5656">|</span> events_waits_summary_by_user_by_event_name           <span style="color:#ab5656">|</span>      <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>           <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> performance_schema <span style="color:#ab5656">|</span> events_waits_summary_global_by_event_name            <span style="color:#ab5656">|</span>      <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>           <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> performance_schema <span style="color:#ab5656">|</span> events_transactions_summary_global_by_event_name     <span style="color:#ab5656">|</span>      <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>           <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> performance_schema <span style="color:#ab5656">|</span> replication_connection_status                        <span style="color:#ab5656">|</span>      <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>           <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> mysql              <span style="color:#ab5656">|</span> time_zone_leap_second                                <span style="color:#ab5656">|</span>      <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>           <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> mysql              <span style="color:#ab5656">|</span> columns_priv                                         <span style="color:#ab5656">|</span>      <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>           <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> my                 <span style="color:#ab5656">|</span> test03                                               <span style="color:#ab5656">|</span>      <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>           <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> bigdata            <span style="color:#ab5656">|</span> mylock                                               <span style="color:#ab5656">|</span>      <span style="color:#880000">1</span> <span style="color:#ab5656">|</span>           <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>
...
</code></span></span>

In_use being 1 means that the mylock table of this library has been locked.

Release the lock

<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">mysql<span style="color:#ab5656">></span> unlock tables;
Query OK, <span style="color:#880000">0</span> <span style="color:#0000ff">rows</span> affected (<span style="color:#880000">0.00</span> sec)
</code></span></span>

Add read lock - add read lock to mylock table (read block write example)

Multiple sessions can simulate a distributed situation: when session 1 locks table A, other sessions can only read the table, and updates and inserts will be blocked.

3- Read lock case explanation 2

Add a write lock to the mylock table (a write blocking read example of the MylSAM storage engine)

After adding a write lock to session1 ( you can play as you like ), other sessions cannot read it!

Case conclusion

Before executing the query statement (SELECT), MyISAM will automatically add read locks to all the tables involved, and before performing addition, deletion, and modification operations, it will automatically add write locks to the tables involved.

MySQL's table-level locks have two modes:

  • Table shared read lock (Table Read Lock)

  • Table exclusive write lock (Table Write Lock)

lock type Compatibility read lock write lock
read lock yes yes no
write lock yes no no

Combined with the above table, the operation on the MyISAM table will have the following conditions:

  1. The read operation ( read lock ) on the MyISAM table will not block other processes' read requests to the same table , but will block the write requests to the same table . Only when the read lock is released, the write operation of other processes will be performed.

  2. The write operation ( adding a write lock ) to the MyISAM table will block the read and write operations of other processes on the same table . Only after the write lock is released, the read and write operations of other processes will be executed.

In short, read locks will block writing, but will not block reading. The write lock will block both reading and writing.

4- Table lock analysis

If there is a command, let us know which tables are locked and how long they are locked

  • See which tables are locked
<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">mysql<span style="color:#ab5656">></span> <span style="color:#0000ff">show</span> <span style="color:#0000ff">open</span> tables;
</code></span></span>
  • How to analyze table locks

Table locks on your system can be analyzed by examining the table_locks_waited and table_locks_immediate status variables.

<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">mysql<span style="color:#ab5656">></span>  <span style="color:#0000ff">show</span> status <span style="color:#0000ff">like</span> <span style="color:#a31515">'table_locks%'</span>;
<span style="color:#ab5656">+</span><span style="color:#008000">-----------------------+-------+</span>
<span style="color:#ab5656">|</span> Variable_name         <span style="color:#ab5656">|</span> <span style="color:#0000ff">Value</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">-----------------------+-------+</span>
<span style="color:#ab5656">|</span> Table_locks_immediate <span style="color:#ab5656">|</span> <span style="color:#880000">170</span>   <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> Table_locks_waited    <span style="color:#ab5656">|</span> <span style="color:#880000">0</span>     <span style="color:#ab5656">|</span>  #越高锁门锁竞争的越激烈
<span style="color:#ab5656">+</span><span style="color:#008000">-----------------------+-------+</span>
<span style="color:#880000">2</span> <span style="color:#0000ff">rows</span> <span style="color:#0000ff">in</span> <span style="color:#0000ff">set</span> (<span style="color:#880000">0.00</span> sec)
</code></span></span>

There are two status variables here to record the situation of MySQL internal table-level locking. The two variables are described as follows:

  • Table_locks_immediate: The number of table-level locks generated, indicating the number of queries that can immediately acquire locks, and the value of each immediate lock is increased by 1;
  • Table_locks_waited: The number of waits caused by table-level lock contention (the number of times the lock cannot be acquired immediately, and the lock value is increased by 1 each time the lock is waited). A high value indicates that there is a serious table-level lock contention ;

In addition, MyISAM's read-write lock scheduling is write-first, which is why MyISAM is not suitable for writing as the main table engine . Because after writing the lock, other threads cannot do any operations, and a large number of updates will make it difficult for the query to obtain the lock, resulting in permanent blocking.

5- row lock theory

InnoDB storage engine is preferred, with high overhead and slow locking; deadlocks may occur; the locking granularity is the smallest, the probability of lock conflicts is the lowest, and the concurrency is the highest.

There are two biggest differences between InnoDB and MyISAM: one is to support transactions (TRANSACTION); the other is to use row-level locks .

Since row locks support transactions, review old knowledge

  • Transaction (Transaction) and its ACID properties
  • Problems caused by concurrent transaction processing
  • transaction isolation level

A transaction is a logical processing unit composed of a set of SQL statements . A transaction has the following four attributes, which are usually referred to as ACID attributes of a transaction:

  • Atomicity: A transaction is an atomic operation unit, and its modification to data is either all executed or not executed at all.
  • Consistency: Data must remain in a consistent state when a transaction begins and completes. This means that all relevant data rules must be applied to the modification of the transaction to maintain data integrity; at the end of the transaction, all internal data structures (such as B-tree indexes or doubly linked lists) must also be correct.
  • Isolation: The database system provides a certain isolation mechanism to ensure that transactions are executed in an "independent" environment that is not affected by external concurrent operations. This means that the intermediate state during the transaction process is not visible to the outside world, and vice versa.
  • Persistence (Durable): After the transaction is completed, its modification of the data is permanent and can be maintained even if a system failure occurs.

Problems caused by concurrent transaction processing

  • Lost Update
  • Dirty Reads
  • Non-repeatable reads (Non-Repeatable Reads)
  • Phantom Reads

Lost Update

The lost update problem occurs when two or more transactions select the same row and then update that row based on the originally selected value, since each transaction is unaware of the existence of the other transactions -- the last update overwrites the value created by the other transaction. Updates made by the firm.

For example, two programmers modify the same java file. Each programmer independently changes its copy and then saves the changed copy, thus overwriting the original document. The last editor to save a copy of his changes overwrites the changes made by the previous programmer.

This problem can be avoided if another programmer cannot access the same file until another programmer completes and commits the transaction.

Dirty Reads

A transaction is modifying a record. Before the transaction is completed and submitted, the data of this record is in an inconsistent state; at this time, another transaction also reads the same record. If it is not controlled, the second transaction After reading these "dirty" data and further processing based on it, uncommitted data dependencies will be generated. This phenomenon is vividly called "dirty reading".

In a word: Transaction A has read the data that has been modified but not submitted by transaction B, and has performed operations on the basis of this data. At this point, if transaction B is rolled back, the data read by A is invalid and does not meet the consistency requirements. (Maybe I made a mistake and you got the wrong data to work on)

Non-repeatable reads (Non-Repeatable Reads)

A certain time after reading some data, a transaction reads the previously read data again, only to find that the read data has changed, or some records have been deleted! This phenomenon is called " non-repeatable read".

In a word: Transaction A reads the modified data submitted by transaction B, which does not meet the isolation requirements.

Phantom Reads

A transaction re-reads previously retrieved data according to the same query conditions, but finds that other transactions have inserted new data that meets its query conditions. This phenomenon is called "phantom reading".

In a word: Transaction A reads the new data submitted by transaction B, which does not meet the isolation requirements.

One more word: Phantom reading is somewhat similar to dirty reading.

Dirty read is the modification of data in transaction B.

Phantom reading is new data in transaction B.

transaction isolation level

"Dirty reads", "non-repeatable reads" and "phantom reads" are actually database read consistency problems, which must be solved by the database providing a certain transaction isolation mechanism.

Read data—consistency and allowed concurrency side effects (isolation level) read data consistency dirty read non-repeatable read Phantom reading
Uncommitted read (Read Uncommitted) The lowest level, which can only guarantee that physically damaged data will not be read yes yes yes
Committed to read (Read committed) statement level no yes yes
Repeatable read (Repeatable read) transaction level no no yes
serializable highest level, transaction level no no no

The stricter the transaction isolation of the database, the smaller the side effects of concurrency, but the greater the price paid, because transaction isolation essentially makes transactions "serialized" to a certain extent, which is obviously contradictory to "concurrency". At the same time, different applications have different requirements for read consistency and transaction isolation. For example, many applications are not sensitive to "non-repeatable reads" and "phantom reads", and may be more concerned about the ability to concurrently access data.

Often see the transaction isolation level of the current database: show variables like 'tx_isolation';

<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">mysql<span style="color:#ab5656">></span> <span style="color:#0000ff">show</span> variables <span style="color:#0000ff">like</span> <span style="color:#a31515">'tx_isolation'</span>;
<span style="color:#ab5656">+</span><span style="color:#008000">---------------+-----------------+</span>
<span style="color:#ab5656">|</span> Variable_name <span style="color:#ab5656">|</span> <span style="color:#0000ff">Value</span>           <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">---------------+-----------------+</span>
<span style="color:#ab5656">|</span> tx_isolation  <span style="color:#ab5656">|</span> REPEATABLE<span style="color:#ab5656">-</span>READ <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">---------------+-----------------+</span>
<span style="color:#880000">1</span> <span style="color:#a31515">row</span> <span style="color:#0000ff">in</span> <span style="color:#0000ff">set</span>, <span style="color:#880000">1</span> warning (<span style="color:#880000">0.00</span> sec)
</code></span></span>

MySQL defaults to the transaction level, and phantom reading may occur.

6- Row lock case explanation

New SQL

<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">#使用INNODB引擎
<span style="color:#0000ff">CREATE</span> <span style="color:#0000ff">TABLE</span> test_innodb_lock (a <span style="color:#a31515">INT</span>(<span style="color:#880000">11</span>),b <span style="color:#a31515">VARCHAR</span>(<span style="color:#880000">16</span>))ENGINE<span style="color:#ab5656">=</span>INNODB;

<span style="color:#0000ff">INSERT</span> <span style="color:#0000ff">INTO</span> test_innodb_lock <span style="color:#0000ff">VALUES</span>(<span style="color:#880000">1</span>,<span style="color:#a31515">'b2'</span>);
<span style="color:#0000ff">INSERT</span> <span style="color:#0000ff">INTO</span> test_innodb_lock <span style="color:#0000ff">VALUES</span>(<span style="color:#880000">3</span>,<span style="color:#a31515">'3'</span>);
<span style="color:#0000ff">INSERT</span> <span style="color:#0000ff">INTO</span> test_innodb_lock <span style="color:#0000ff">VALUES</span>(<span style="color:#880000">4</span>, <span style="color:#a31515">'4000'</span>);
<span style="color:#0000ff">INSERT</span> <span style="color:#0000ff">INTO</span> test_innodb_lock <span style="color:#0000ff">VALUES</span>(<span style="color:#880000">5</span>,<span style="color:#a31515">'5000'</span>);
<span style="color:#0000ff">INSERT</span> <span style="color:#0000ff">INTO</span> test_innodb_lock <span style="color:#0000ff">VALUES</span>(<span style="color:#880000">6</span>, <span style="color:#a31515">'6000'</span>);
<span style="color:#0000ff">INSERT</span> <span style="color:#0000ff">INTO</span> test_innodb_lock <span style="color:#0000ff">VALUES</span>(<span style="color:#880000">7</span>,<span style="color:#a31515">'7000'</span>);
<span style="color:#0000ff">INSERT</span> <span style="color:#0000ff">INTO</span> test_innodb_lock <span style="color:#0000ff">VALUES</span>(<span style="color:#880000">8</span>, <span style="color:#a31515">'8000'</span>);
<span style="color:#0000ff">INSERT</span> <span style="color:#0000ff">INTO</span> test_innodb_lock <span style="color:#0000ff">VALUES</span>(<span style="color:#880000">9</span>,<span style="color:#a31515">'9000'</span>);
<span style="color:#0000ff">INSERT</span> <span style="color:#0000ff">INTO</span> test_innodb_lock <span style="color:#0000ff">VALUES</span>(<span style="color:#880000">1</span>,<span style="color:#a31515">'b1'</span>);

<span style="color:#0000ff">CREATE</span> INDEX test_innodb_a_ind <span style="color:#0000ff">ON</span> test_innodb_lock(a);
<span style="color:#0000ff">CREATE</span> INDEX test_innodb_lock_b_ind <span style="color:#0000ff">ON</span> test_innodb_lock(b);
</code></span></span>

operation result

<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">mysql<span style="color:#ab5656">></span> <span style="color:#0000ff">select</span> <span style="color:#ab5656">*</span> <span style="color:#0000ff">from</span> test_innodb_lock;
<span style="color:#ab5656">+</span><span style="color:#008000">------+------+</span>
<span style="color:#ab5656">|</span> a    <span style="color:#ab5656">|</span> b    <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">------+------+</span>
<span style="color:#ab5656">|</span>    <span style="color:#880000">1</span> <span style="color:#ab5656">|</span> b2   <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>    <span style="color:#880000">3</span> <span style="color:#ab5656">|</span> <span style="color:#880000">3</span>    <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>    <span style="color:#880000">4</span> <span style="color:#ab5656">|</span> <span style="color:#880000">4000</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>    <span style="color:#880000">5</span> <span style="color:#ab5656">|</span> <span style="color:#880000">5000</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>    <span style="color:#880000">6</span> <span style="color:#ab5656">|</span> <span style="color:#880000">6000</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>    <span style="color:#880000">7</span> <span style="color:#ab5656">|</span> <span style="color:#880000">7000</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>    <span style="color:#880000">8</span> <span style="color:#ab5656">|</span> <span style="color:#880000">8000</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>    <span style="color:#880000">9</span> <span style="color:#ab5656">|</span> <span style="color:#880000">9000</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>    <span style="color:#880000">1</span> <span style="color:#ab5656">|</span> b1   <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">------+------+</span>
<span style="color:#880000">9</span> <span style="color:#0000ff">rows</span> <span style="color:#0000ff">in</span> <span style="color:#0000ff">set</span> (<span style="color:#880000">0.00</span> sec)

mysql<span style="color:#ab5656">></span> <span style="color:#0000ff">show</span> index <span style="color:#0000ff">from</span> test_innodb_lock;
</code></span></span>

image-20210515162559758

Basic demonstration of row locking (two clients update the same row record)

Read what I wrote , because the data in session1 has not been submitted, so the latest data cannot be read in session2; it can be compared: posting to Moments, I can definitely see it at the first time, but other The user cannot guarantee that the update will arrive at the first time, and it should be delayed for a few seconds (distributed system), which cannot satisfy strong consistency;

When two sessions modify the same row of data, the later ones will be blocked; when the modification is not the same row of data, they will not interfere with each other (the road goes to the sky on each side ).

7- row lock demo Q & A supplement

Session2 also needs to re-commit to refresh the latest data: the reason is that the commit of session2 is also set to 0. If the MySQL default commit=1, the latest data can be obtained when reading.

8-Index failure causes row lock to table lock

Upgrade non-indexed row locks to table locks

9- Gap lock hazard

What is a gap lock

When we use range conditions instead of equality conditions to retrieve data and request shared or exclusive locks, InnoDB will lock the index items of existing data records that meet the conditions . For records whose key values ​​​​are within the condition range but do not exist , Called "Gap (GAP)".

InnoDB will also lock this "gap". This locking mechanism is the so-called gap lock (Next-Key lock). In the above case, there is no record of a=2, but MySQL still locks this record. .

【harm】

Because if the query passes through the range search during execution, it will lock all the index key values ​​in the entire range, even if the key value does not exist.

Gap lock has a relatively fatal weakness, that is, after locking a range of key values, even some non-existing key values ​​will be innocently locked, resulting in the inability to insert any data within the locked key value range during locking. In some scenarios this can be very harmful to performance.

10-Interview question: How to lock a row

Interview: How to lock a row? begin...commit

I hope that this data cannot be modified by other threads when operating this data.

11- Summary of row locks and page locks

Because the Innodb storage engine implements row-level locking, although the performance loss caused by the implementation of the locking mechanism may be higher than that of table-level locking, it is far superior to MyISAM's table-level in terms of overall concurrent processing capabilities. locked. When the system concurrency is high, the overall performance of Innodb will have obvious advantages compared with MylISAM.

However, Innodb's row-level locking also has its fragile side. When we use it improperly, the overall performance of Innodb may not only be higher than that of MyISAM, but may even be worse. (Improper use, row locks become table locks)

①Row lock analysis

How to Analyze Row Locks

Analyze row lock contention on your system by examining the lnnoDB_row_lock status variable

<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">mysql<span style="color:#ab5656">></span>  <span style="color:#0000ff">show</span> status <span style="color:#0000ff">like</span> <span style="color:#a31515">'innodb_row_lock%'</span>;
<span style="color:#ab5656">+</span><span style="color:#008000">-------------------------------+--------+</span>
<span style="color:#ab5656">|</span> Variable_name                 <span style="color:#ab5656">|</span> <span style="color:#0000ff">Value</span>  <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">-------------------------------+--------+</span>
<span style="color:#ab5656">|</span> Innodb_row_lock_current_waits <span style="color:#ab5656">|</span> <span style="color:#880000">0</span>      <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> Innodb_row_lock_time          <span style="color:#ab5656">|</span> <span style="color:#880000">128380</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> Innodb_row_lock_time_avg      <span style="color:#ab5656">|</span> <span style="color:#880000">32095</span>  <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> Innodb_row_lock_time_max      <span style="color:#ab5656">|</span> <span style="color:#880000">50618</span>  <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> Innodb_row_lock_waits         <span style="color:#ab5656">|</span> <span style="color:#880000">4</span>      <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">-------------------------------+--------+</span>
<span style="color:#880000">5</span> <span style="color:#0000ff">rows</span> <span style="color:#0000ff">in</span> <span style="color:#0000ff">set</span> (<span style="color:#880000">0.01</span> sec)
</code></span></span>

The description of each status quantity is as follows:

  • Innodb_row_lock_current_waits: the number currently waiting for locks;
  • Innodb_row_lock_time: the total length of time locked from system startup to now;
  • Innodb_row_lock_time_avg: the average time spent waiting each time;
  • Innodb_row_lock_time_max: the time it takes to wait for the most frequent time from system startup to now;
  • Innodb_row_lock_waits: the total number of waits since the system started;

For these five state variables, the more important ones are

  • Innodb_row_lock_time_avg (average waiting time)
  • lnnodb_row_lock_waits (total number of waits)
  • lnnodb_row_lock_time (total waiting time) these three items.

Especially when the number of waits is high and the waiting time is not small each time, we need to analyze why there are so many waits in the system, and then proceed to specify an optimization plan based on the analysis results (showProfile can be used ) .

②Optimization suggestions

  • As much as possible, all data retrieval is done through the index to avoid the upgrade of non-indexed row locks to table locks.
  • Reasonably design indexes to minimize the scope of locks
  • Fewer search conditions as possible to avoid gap locks
  • Try to control the transaction size, reduce the amount of locked resources and the length of time
  • Low-level transaction isolation as possible
  • The varchar type must be added with single quotes!

③page lock

The overhead and locking time are between table locks and row locks; there will be deadlocks; the locking granularity is between table locks and row locks, and the concurrency is average. (Learn about it)

Guess you like

Origin blog.csdn.net/m0_60961651/article/details/132272847