mysql RR隔离级别锁

2024年 3月 22日 81.8k 0

mysql锁对象 lock_type

LOCK_TABLE 表锁

LOCK_REC 行锁

mysql锁模式lock_mode

LOCK_IS

LOCK_IX

LOCK_S

LOCK_X

LOCK_AUTO_INC

mysql锁类型

LOCK_ORDINARY :lock_mode x/s

LOCK_GAP : lock_mode x locks gap before rec

LOCK_REC_NOT_GAP lock_mode x/s locks rec but not gap

LOCK_INSERT_INTENTION

数据准备

create database testdb;
use testdb;
CREATE TABLE `lock_test` (
`id` int(11) NOT NULL,
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `a` (`a`)
) ENGINE=InnoDB;

insert into lock_test values(0,0,0),(5,5,5),(10,10,10),(15,15,15),(20,20,20),(25,25,25);
select * from lock_test;


打开4个session,开启RR隔离级别

SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

在第四个session查看加锁情况

select * from performance_schema.data_lock_waits;
select * from performance_schema.data_locks
show engine innodb status G;

1.无索引

等值查询
查询值存在
时间 session1 session2 session3
T1 begin;update lock_test set b=b+1 where b=5;
T2 begin;insert into lock_test values(8,8,8);(blocking)
T3 begin;update lock_test set b=b+1 where b=10;
T4 rollback (blocking)

T1:表上加lock mode IX,主键索引上所有行上加“lock_mode X locks rec”

T2: session2等待“lock_mode X locks gap before rec insert intention waiting”

T3: session3等待"lock_mode X waiting"

T4:session1 rollback ,session3进入执行持有所有“lock_mode X”,session 2等待“lock_mode X locks gap before rec insert intention waiting”

说明:

a.无索引情况下更新操作,按主键锁定所有记录

b.session3比session2先进入执行,“插入意向” 不阻塞 “gap”,gap阻塞 “插入意向”

查询值不存在
时间 session1 session2 session3
T1 begin;update lock_test set b=b+1 where b=7;
T2 begin;insert into lock_test values(8,8,8); (blocking)
T3 begin;update lock_test set b=b+1 where b=10; (blocking)

T1:表上加lock mode IX,主键索引上所有行上加“lock_mode X”

T2: session2等待“lock_mode X locks gap before rec insert intention waiting”

T3: session3等待"lock_mode X waiting"

范围查询
查询值存在
时间 session1 session2 session3
T1 begin;select * from lock_test where b11 for update;
T2 begin;insert into lock_test values(8,8,8);(blolcking)
T3 begin;update lock_test set b=b+1 where b=10;           (blocking)

T1:表上加lock mode IX,主键索引上所有行上加“lock_mode X locks rec”

T2: session2等待“lock_mode X locks gap before rec insert intention waiting”

T3: session3等待"lock_mode X waiting"

结论:处于RR隔离级别下,无索引查询会锁定所有记录,不区分范围查询,等值查询

2.唯一索引

等值查询
查询值存在
时间 session1 session2 session3
T1 begin;select * from lock_test where id=5 for update;
T2 begin;insert into lock_test values(8,8,8);
T3 begin;update lock_test set b=b+1 where id=10;

T1:表上加lock mode IX,主键索引上所有行上加“lock_mode X locks rec but not gap”

T2: session2 表上加lock mode IX 不阻塞;插入后意向锁释放

T3: session3 表上加lock mode IX,“lock_mode X locks rec but not gap” 不阻塞

结论:2.等值查询,唯一索引,行锁

查询值不存在
时间 session1 session2 session3
T1 begin;select * from lock_test where id=7 for update;
T2 begin;insert into lock_test values(7,7,7); (blocking)
T3 begin;update lock_test set b=b+1 where id=10;

T1:在id=10的位置加 “lock_mode X locks gap before rec”

T2:阻塞,在id=10的位置 “lock_mode X locks gap before rec insert intention waiting”,间隙锁阻塞插入意向锁

T3:不阻塞,session 3加 “lock_mode X locks rec but not gap”



结论:2.等值查询,唯一索引,行不存在间隙锁

唯一索引记录存在只加记录锁,不存在下一个键位置上加间隙锁 lock_mode X locks gap before rec insert intention waiting

范围查询
查询值存在
时间 session1 session2 session3
T1 begin;select * from lock_test where id>=5 and id=6 and id=6 and id

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论