MySQL row lock intention lock gap lock

MySQL row lock intention lock gap lock

First, the classification of locks

Shared lock : Anyway, I understand it as a read lock. Transaction A adds a shared lock to some data, allowing other transactions to acquire these data shared locks at the same time, but it is not possible to add exclusive locks on these data.

Exclusive lock : understand it as a write lock, transaction A adds an exclusive lock to some data, then other transactions are no longer allowed to add shared locks or exclusive locks.

Understanding: Let's put it this way~ Transaction A reads a record, transaction B can also read this record, but he can't make changes (that is, he can't do write operations). Transaction A modifies a record, and transaction B cannot read or write this record.

Read lock : Transaction A adds a read lock to some records, so other transactions can also read the data with a read lock, but cannot write to it (it can be understood as it cannot be modified)

Write lock : Transaction A adds a write lock to some records (generally making some modifications or the like), then other transactions can no longer write and read these data

Row lock : It is a lock in a row unit. There are also branch read locks and row write locks.

Table lock : table-level lock ~ lock an entire table with one lock

Intent lock : table-level lock. Divided into intent shared lock and intent exclusive lock

**Why is there an intention lock? **I am based on the innodb engine~ its function, we can analyze it through the following example:

There are row locks and table-level locks under innodb.

If transaction A wants to add a table write lock to a table, it is definitely not allowed for this table to have other transactions B that have already added a row write lock on a certain row of data. So how does mysql retrieve the data in a table if there is a row write lock, and look at it one by one. Is the efficiency too low? So the intention lock is derived here. If transaction B adds a row write lock to a row of data (an exclusive lock), then B will also add an intent exclusive lock to this table. When transaction A adds a table lock, transaction A will see this With the intention exclusive lock on the table, transaction A no longer performs the lock operation.

Below we focus on row locks

Two, row lock

Row lock demo

Table structure: id is the primary key, idx_name_age_sex (name ,age ,sex`) composite index

DROP TABLE IF EXISTS `tuser`;
CREATE TABLE `tuser`  (
  `id` int(11) NOT NULL,
  `name` varchar(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `age` int(11) NULL DEFAULT NULL,
  `sex` varchar(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `comment` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `idx_name_age_sex`(`name`, `age`, `sex`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

data

INSERT INTO `tuser` VALUES (1, '张三', 24, '1', '否');
INSERT INTO `tuser` VALUES (2, '李四', 33, '1', '2');
INSERT INTO `tuser` VALUES (3, '王五', 26, '1', '33');
INSERT INTO `tuser` VALUES (4, '苏六', 28, '2', '33');
INSERT INTO `tuser` VALUES (5, '赵期', 22, '1', '11');
INSERT INTO `tuser` VALUES (6, '刘芳', 26, '2', '无');

SET FOREIGN_KEY_CHECKS = 1;

session1

BEGIN;

select * from tuser where name = '张三' lock in share mode;

session2:

BEGIN;

UPDATE tuser set age =38 where name='张三';

Explain: session1 opens the transaction and executes the select lock in share mode statement. At this time, the row read lock will be added to the record with name='Zhang San', and no commit will be made; at this time, session2 will open the transaction, and for the record with name='Zhang San' The data performs the update operation, and the result is blocked, as shown in the following figure:
Insert picture description here

Note: After the transaction is committed, the lock can be understood as released.

Three, gap lock

Gap lock : It is easy to understand and lock a gap. Prevent other transactions from inserting data into the gap, or update the data to the value in the gap

Here is a Next-Key. The current read of RR isolation level relies on next-key to solve the problem of phantom reading. Snapshot reads use mvcc to solve the problem of phantom reading.

Next-key: record lock + gap lock

The following is the lock situation under the RR isolation level of various situations that I summarized. First, simply refer to it. You don't need to memorize, just understand it. If you don't understand, do an experiment and try it yourself.

Insert picture description here

Demo

Table structure and data look at the picture

Insert picture description here

1. Auxiliary index

1) Equivalent query

a) Hit record

session1

BEGIN;

select * from user where num=10 lock in share mode;

COMMIT;

session2:

BEGIN;

INSERT INTO `user` VALUES (9,11,22);

COMMIT;

Execution result : blocking

Insert picture description here

analysis

Insert picture description here

Session1 takes the equivalent query of the auxiliary index and hits the record, so record lock + gap lock will be generated. The position of the gap lock lock is the position in the above figure, and the record lock is the row of num=10 on the auxiliary index tree and the record of num=10 on the primary key index tree (although it is the same data, but the primary key index Both the tree and the auxiliary index tree must be locked).

b) No hit

session1

BEGIN;

select * from user where num=13 lock in share mode;

session2

BEGIN;

INSERT INTO `user` VALUES (9,14,22);

INSERT INTO `user` VALUES (9,16,22);

Effect screenshot : (9,14,22) blocked, (9,16,22) succeeded

Insert picture description here

Insert picture description here

analysis

Insert picture description here

First of all, our sql uses an auxiliary index to perform equivalent queries, but there is no hit record, so only gap locks will be generated, and record locks will not be generated. The range of the gap lock is shown in the figure above.

2) Range query

a) Hit record

session1

BEGIN;

select * from user where num>6 and num <11  lock in share mode;

session2

BEGIN;

INSERT INTO `user` VALUES (9,6,22);

Effect screenshot :

Analysis :

Insert picture description here

session1 is a range query of the auxiliary index, and the record with num of 10 is hit, so record lock + gap lock will be generated. The position of the gap lock lock is the position in the above figure, and the record lock is the row of num=10 on the auxiliary index tree and the record of num=10 on the primary key index tree (although it is the same data, but the primary key index Both the tree and the auxiliary index tree must be locked).

b) No hit record

session1

BEGIN;

select * from user where num>7 and num <9  lock in share mode;

session2

BEGIN;

INSERT INTO `user` VALUES (9,6,22);

Effect screenshot :
Insert picture description here

Analysis :
Insert picture description here

First of all, our sql uses an auxiliary index for range query, but there is no hit record, so only gap locks will be generated, and record locks will not be generated. The range of the gap lock is shown in the figure above.

2. Primary key index

1) Equivalent query

a) Hit record

session1

BEGIN;

select * from user where id=8  lock in share mode;

session2

BEGIN;

INSERT INTO `user` VALUES (9,6,22);

Effect screenshot :

Insert picture description here

analysis

For this sql, we use the equivalent query of the primary key index and hit the record with id=8. Only the record lock will be generated here, that is, the record with id=8 on the primary key index tree is locked. There is no gap lock.

b) No hit record

session1

BEGIN;

select * from user where id=17  lock in share mode;

session2

BEGIN;

INSERT INTO `user` VALUES (18,18,22);

Effect screenshot

Insert picture description here

analysis

Insert picture description here

For this sql, we use the equivalent query of the primary key index. There is no hit record, and only gap locks will be generated here. The gap lock range is shown in the figure above.

2) Range query

a) Hit record

session1

BEGIN;

select * from user where id>14 and id <17  lock in share mode;

session2

BEGIN;

INSERT INTO `user` VALUES (18,6,22);

Effect screenshot

Insert picture description here

analysis

Insert picture description here

For this sql, we use the range query of the primary key index, and it hits the record with id=15. There will be gap locks and record locks. The gap lock range is shown in the figure above. The record lock locks the row of num=15 on the primary key index tree.

b) No hit record

session1

BEGIN;

select * from user where id>16 and id <18  lock in share mode;

session2

BEGIN;

INSERT INTO `user` VALUES (19,6,22);

Effect screenshot

Insert picture description here

analysis

Insert picture description here

For this sql, we use the range query of the primary key index. There is no hit record, and only gap locks will be generated here. The gap lock range is shown in the figure above.

Guess you like

Origin blog.csdn.net/weixin_44969687/article/details/107028262