Performance optimization|Using this method, if you don’t believe it, you can’t remember the mysql high-frequency interview knowledge points

Search on WeChat [AI Coder] Follow the handsome me, reply [Receive dry goods], and receive a copy of the latest interview information for 2021

Understanding of table locks and row locks

Table lock

  • Definition When
    performing table operations, mysql will lock the entire table, locking and unlocking efficiency is very high, there will be no deadlock competition, but it will cause lock blocking, resulting in low concurrency.
  • command
    • Manually add table lock:
      lock table tableName1 read[write],tableName2 read[write];
    • View the locks added on the table:

      show open tables where in_use > 0;
    • Unlock:

      UNLOCK tables;
  • Actual combat
    Create an initialized table:
   SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `locak_table`;
CREATE TABLE `locak_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `score` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
BEGIN;
INSERT INTO `locak_table` VALUES (1, '刘备', 350);
INSERT INTO `locak_table` VALUES (2, '张飞', 16000);
INSERT INTO `locak_table` VALUES (3, '关羽', 2400);
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;

The circle in the picture is turning to indicate that it is blocked

  • Session A adds a write lock to the table, session B is blocked for reading or writing
    Insert picture description here
    Insert picture description here
    Insert picture description here
  • Session A adds a read lock to the table, session B writes will be blocked, read is not blocked
    Insert picture description here
    Insert picture description here
    Insert picture description here

Row lock

definition

Adding a lock for each row of data is slow and prone to deadlock competition. Because each row of data is locked, the lock strength is small, so the concurrency is high. Innodb supports row-level locks, and row-level locks support transactions.

ACID properties of row-level lock transactions

  • Atomicity: In order to complete a business, multiple database modification statements need to be executed. If any of these statements fails, the state before the execution of the first statement will all be rolled back. If there are no failed statements, the execution is successful. , One sentence understanding: either all of them are executed, or all are not executed.
  • Consistency: Consistency focuses on keeping the state before the transaction started and the state in the library at the end of the transaction.
  • Isolation: In the process of executing things, operations on the database are invisible to other transactions. Only after the transaction is submitted can the outside world see the changed data.
  • Persistence: All modifications made to the database by the transaction must be permanently stored in the disk file (in the database).

Concurrency problems caused by multiple transactions operating data at the same time

  • Dirty read
    There are two transactions A and B. If transaction A modifies the contents of the database and is read by transaction B, then A rolls back the transaction. At this time, the transaction read by B does not exist. This is a dirty read ( Read data that does not exist )

  • Non-repeatable read
    Transaction A uses the same query conditions to query the database. The results of the two queries are inconsistent. Transaction A reads data that has been submitted and modified by other transactions . This is non-repeatable read.

  • Phantom reading
    In a transaction,
    1. Transaction A first searches the database according to the retrieval condition of id 1, and finds that there is no such record
    . 2. After transaction A is queried, transaction B inserts a record with id 1.
    3. In order to ensure the correctness of the business, transaction A performs a series of operations and queries it again to ensure that the record does not exist. Due to the repeatable isolation, the record cannot be found at this time.
    3. After transaction A judges that there is no such record, it inserts one into the library, but at this time it will find that there are two records in the library, which violates the business logic.
    This is just one of the simulated scenes of the phantom reading.

    This is purely personal understanding, if you have different opinions, you can ignore this explanation! ! !

How to solve these concurrency problems? MySQL uses four isolation levels to solve, the first level is stronger than the first level, and the concurrency level is lower than the first level.

Transaction isolation level

  • Read uncommitted: the lowest level and the highest number of concurrency. Dirty reads, non-rereadable reads, and phantom reads may occur. It can also be said that the problems caused by transaction concurrency are not solved at all. This level can be used in scenarios with fewer write operations.
  • Reading submitted: non-repeatable reading and phantom reading may occur.
  • Repeatable reading: phantom reading may occur
  • Serializable: Completely solve the concurrency problem, it uses "single thread" to control the execution order of transactions.

The default transaction isolation level of mysql is: read committed (REPEATABLE-READ)
Set isolation level: set tx_isolation='REPEATABLE-READ';
query supported transaction isolation level: show variables like'tx_isolation';

Verification of transaction isolation level

Initialize SQL:

CREATE TABLE `locak_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
INSERT INTO `xnyh`.`locak_table`(`id`, `name`, `age`) VALUES (1, '刘备', 350);
INSERT INTO `xnyh`.`locak_table`(`id`, `name`, `age`) VALUES (2, 'hanmei', 16000);
INSERT INTO `xnyh`.`locak_table`(`id`, `name`, `age`) VALUES (3, 'lucy', 2400);
  • Verification read not submitted

Transaction A operation
Insert picture description here

Transaction B has operated on the database, but the transaction has not yet been committed
Insert picture description here

Execute the query statement again in transaction A and find that the modification of transaction B has been queried by transaction A
Insert picture description here

In business operations, we generally take out the data we read and do update operations. If age+100 is needed now, the result of updating transaction A to the database is 400, but if transaction B is rolled back, the database The age will be restored to the state of 350. If transaction B updates 400 to the database at this time, 400 is equivalent to 350 and the operation of adding 100 is not executed, so dirty reads occur, causing business data problems.

If you need to read data that others ensure that it will not be rolled back, you must set the isolation level to read-committed

  • Verify that the read has been submitted
    set tx_isolation='read-committed';

    transaction A performs the same operation

    Insert picture description here


Transaction B
Insert picture description here


Transaction A executed the query statement again and found that no uncommitted statement of B was queried, which solved the dirty read problem
Insert picture description here


Transaction B commits the transaction
Insert picture description here

Transaction A performs a query again and finds that it reads the modified data submitted by others
Insert picture description here

Although this solves the problem of dirty reads, it will cause a new problem, that is, the same query conditions, inconsistent query results, resulting in non-repeatable read problems, which again have to set the isolation level to repeatable read to solve.

  • Verify repeatable read

    set tx_isolation='repeatable-read';

    Because in 5.7, the default transaction isolation level of mysql is repeatable read , so you don't need to make declaration settings.
    It should be noted that the verification can be repeated reading, and the navcat client can no longer be used to execute sql. I have tried several times and found that the verification of repeated reading in navcat will fail. The specific reason has not been studied. We now use the mysql command line to verify.
    Transaction A sets the transaction to be rereadable and query
    Insert picture description here


    Transaction B modifies data and commits

    Insert picture description here

Transaction A queries again:

Insert picture description here

It is found that the query result is the same as before. What effect will happen if we modify age in transaction A at this time?
Insert picture description here

Everyone thinks, what should be in the library now, is it 300+300 or 321+300?
Insert picture description here

It can be seen that 300+300=600, the modified data of transaction B is used, that is, when transaction A executes the modification operation, it will use the latest state in the library to modify, thereby ensuring the consistency of the data. The mechanism is in the repeatable read isolation level, MySQL uses the MVCC (multi-version concurrency control) mechanism to achieve. The specific implementation mechanism will be introduced at the end.

Now we have verified the repeatable reading, but you should not think that repeatable reading is perfect. It is also flawed. There may be a phenomenon of phantom reading. The understanding of phantom reading has been explained before. Students can look back and see it again.

Now that there is a problem of phantom reading, how does mysql solve it?
1. Use serialization. There is no explanation for this. Each transaction is executed in sequence like a "single thread";
2. In some scenarios, gap locks can be used to solve

  • How does the gap lock solve the problem of phantom reading?
    Gap lock is to lock the index of a certain range interval. When you open the transaction and use the gap lock
    , then other users cannot access the data in the operator range. If you are in the re-readable isolation mode, you can add for update to the SQL statement to let MySQL add a gap lock to the index. For example,
    I want to query whether the record with id = 10 exists. If it does not exist, insert one.
    select * from locak_table where id = 10 for update;

    When MySQL finds the index If there is this record, the row lock will be added, if not, the gap lock will be used: If the largest auto-increment ID in the database is 8, then the range of the gap lock at this time is that the values ​​in the interval 8-11 are locked. Other data cannot be inserted.
    If no index is created for the current field, it will be upgraded to a table lock.

MVCC mechanism

definition

The implementation of MVCC in MySQL InnoDB is mainly to improve the concurrency performance of the database, and to deal with read-write conflicts in a better way, so that even when there is a read-write conflict, it can be read without locking and non-blocking concurrent reading.

What is current read and snapshot read

  • Current Read
    Read the latest data record in the transaction, and ensure that after reading it, other transactions cannot concurrently modify the current data.
  • Snapshot Read
    Snapshot Read does not need to lock to read the data in the database. It relies on a multi-version mechanism. After the transaction is opened, it will be assigned a newest transaction ID. It will only read the data that is less than or equal to the current transaction ID. Data, that is, it is possible that he will read the historical version of the data, but the data she reads will not change. This is the implementation mechanism of MVCC, which is why MVCC can solve the problem of non-repeatable reading.

Benefits of MVCC

  • Multi-version concurrency control (MVCC) is a lock-free concurrency control used to resolve read-write conflicts, that is, a one-way increasing timestamp is assigned to a transaction, a transaction ID is saved for each modification, and the read operation reads only the transaction A snapshot of the database before the start. So MVCC can solve the following problems for the database

  • When reading and writing to the database concurrently,
    it is possible to avoid blocking write operations during read operations and write operations without blocking read operations. This improves the performance of concurrent database reads and writes and also solves transaction isolation such as dirty reads, phantom reads, and non-repeatable reads. Problem, but does not solve the missing update problem

The concrete realization of MVCC

Innodb's MVCC mechanism expands two virtual fields (create transaction ID, delete transaction ID) for each row record in the database at the bottom. When we add data to the data, we will save the current transaction in the creation transaction ID field of the record ID; when deleting a record, the current transaction ID will be saved in the delete transaction ID in the deleted data, and the data will not be deleted directly; when updating the data, the current modified data will be copied out and inserted into the library, and then The creation transaction ID of the record is the current transaction ID, and the deletion transaction ID of the old record is updated to the current transaction ID; let's see how to add, delete, modify, and check.
Assume that the latest transaction ID in the current library is 1

  • Demonstrate adding data
begin;
 
  INSERT INTO `xnyh`.`locak_table`(`id`, `name`) VALUES (1, '张飞');
  INSERT INTO `xnyh`.`locak_table`(`id`, `name`) VALUES (2, '刘备');
  commit;

After executing the above statement, the latest transaction ID in the library is 2. It should be noted that the transaction ID is not assigned a new transaction ID after begin, only you are executing the update or insert or delete statement After that, it will apply to mysql for a new transaction ID

At this time, the data in the table should be like this

id name Create transaction ID Delete transaction ID
1 Zhang Fei 2 Undefined
2 Liu Bei 2 Undefined

If the transaction ID is 1 for query at this time, it will not be queried because the creation transaction ID recorded in the database is greater than 1.

  • Demo modify data
begin;
update locak_table set name= '刘禅' where id =1;
commit;

The transaction ID is currently 3

  • MySQL first copies a current record, inserts it into the database, and changes the name to a new value, creates a transaction ID and saves it as the current transaction ID.
  • Update the delete transaction ID of the old data to the
    current record in the current transaction ID table like this:
id name Create transaction ID Delete transaction ID
1 Zhang Fei 2 3
2 Liu Bei 2 Undefined
1 Liu Chan 3 Undefined

If the transaction ID is 2 at this time, the newly modified data cannot be queried. The query conditions are such that the
creation transaction ID must be less than or equal to 2 and the delete transaction ID is greater than 2 or undefined.
So the data found in transaction 2 is still 2

  • Deletion verification The
    deletion and update operations are the same, but there is no need to copy a new piece of data, just assign the current transaction ID to the delete transaction ID of the deleted record.

    At the end of the article, I leave a question for everyone:

    If there are currently two transactions A and B, if transaction A enters the open transaction, and obtains the transaction ID of 10, after transaction B opens the transaction, and obtains the transaction ID of 11, if this time the transaction ID10 adds one to the library Record and submit it. Can I find the transaction ID 11? If it cannot be found, why is it? Welcome everyone to leave a message below to answer.

Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_34311210/article/details/109141560