TIDB 行锁问题

【 TiDB 使用环境】生产环境
【 TiDB 版本】v7.5.2
【复现路径】
session 1:
start transaction;
select * From tab where column1 = 1 for update添加行锁

session 2:
update tab set column2 = ‘b’ where column1 = 1; 此时session会锁阻塞住

session 3:
insert into tab values (column1, column2); 为何session没有被阻塞住呢

session 1:
start transaction;
select * From tab where column1 = 1 for update添加行锁 只会锁住 column1 = 1 所在行的数据,其他不符合条件的不会上锁,且行锁与insert select 不冲突

符合column1 = 1的条件会有10行记录,如果对这10行记录进行update操作肯定是会锁阻塞的,但是如果在insert一条column = 1的数据居然成功了,可是mysql innodb引擎就会把insert操作也阻塞住,不确定是不是gap lock的原因导致的

就是 gap lock 的原因,TiDB 跟 Mysql 加锁方式不一样哦

mysql的原理

Insert column1和column2的具体值是多少呢

c1,c2的新数据不在这个lock区间

看来想锁住insert操作还比较难实现了,之前测试rocksdb引擎也有这个问题

这不是问题哦,符合产品设计预期哦

题主说的是mysql RR隔离级别的gap锁吧,要看具体insert的数据哦,因为mysql的gap锁是左闭右开的一段区间,并不是会锁住所有的insert操作。
例如:
mysql RR隔离级别下
session1:

CREATE TABLE `test100` (
  `id` int(11) NOT NULL,
  `id1` int(11) DEFAULT NULL,
  `name` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_id1` (`id1`)
) ENGINE=InnoDB

insert into test.test100 values(1,1,'a'),(2,5,'a'),(3,10,'a'),(4,15,'b');

begin;
select * from test100 where id1 =10 for update;

session2:

insert into test.test100 values(7,4,'e'); //正常执行
insert into test.test100 values(8,5,'e'); //锁住
insert into test.test100 values(8,8,'e'); //锁住
insert into test.test100 values(8,10,'e'); //锁住
insert into test.test100 values(8,14,'e'); //锁住
insert into test.test100 values(8,15,'e'); //正常执行

即锁住的是 id1为[5,15)这一段。

而tidb没有gap锁的概念,所以不会锁住某个区间。
所以tidb的RR隔离级别其实跟mysql还是有区别的,一般经常用的隔离级别为RC,RC不会出现这种情况呢。

column1 是主键吗?不是主键当然可以插入

是的,tidb确实没有gap lock的概念

此话题已在最后回复的 7 天后被自动关闭。不再允许新回复。