mysql 当前读

目录

 

RR级别当前度如何避免幻读

间隙锁(Gap Lock)

next-key lock

间隙锁和next-key lock的负面影响

加锁规则总结(RR级别)

案例一:等值查询间隙锁

案例二:非唯一索引等值锁

案例三:主键索引范围锁

案例四:非唯一索引范围锁

案例五:唯一索引范围锁bug

案例六:非唯一索引上存在"等值"的例子

案例七:limit 语句加锁

案例八:一个死锁的例子


 

RR级别当前度如何避免幻读

间隙锁(Gap Lock)

跟间隙锁存在冲突关系的,是“往这个间隙中插入一个记录”这个操作。间隙锁之间都不存在冲突关系。

next-key lock

间隙锁和行锁合称next-key lock,每个next-key lock是前开后闭区间。也就是说,我们的表t初始化以后,如果用select * from t for update要把整个表所有记录锁起来,就形成了7个next-key lock,分别是 (-∞,0]、(0,5]、(5,10]、(10,15]、(15,20]、(20, 25]、(25, +suprenum]。

间隙锁记为开区间,把next-key lock记为前开后闭区间。

间隙锁和next-key lock的负面影响

帮我们解决了幻读的问题,但同时也带来了一些“困扰”。

锁住范围更大,更加可能造成死锁,影响并发度。

一些公司解决方案---》读提交隔离级别加binlog_format=row的组合。

 

加锁规则总结(RR级别)

  1. 原则1:加锁的基本单位是next-key lock。next-key lock是前开后闭区间。

  2. 原则2:查找过程中访问到的对象才会加锁。

  3. 优化1:索引上的等值查询,给唯一索引加锁的时候,next-key lock退化为行锁。

  4. 优化2:索引上的等值查询,向右遍历时且最后一个值不满足等值条件的时候,next-key lock退化为间隙锁。

  5. 一个bug:唯一索引上的范围查询会访问到不满足条件的第一个值为止。

案例一:等值查询间隙锁

update t set d=d+1 where c=7;

案例二:非唯一索引等值锁

select id from t c=7 lock in share mode;

案例三:主键索引范围锁

select * from t where id>=10 and id<11 for update;

加锁结果:行锁id=10和next-key lock(10,15]

案例四:非唯一索引范围锁

select * from t where c>=10 and c<11 for update;

加锁结果:索引c上的(5,10] 和(10,15] 这两个next-key lock

案例五:唯一索引范围锁bug

select * from t where id>10 and id<=15 for update;

加锁结果: (10,15]这个next-key lock,(15,20]这个next-key lock也会被锁上。

案例六:非唯一索引上存在"等值"的例子

增加:insert into t values(30,10,30);

加锁结果:(c=5,id=5)到(c=10,id=10)这个next-key lock;(c=10,id=10) 到 (c=15,id=15)的间隙锁。

案例七:limit 语句加锁

案例七里的delete语句明确加了limit 2的限制,因此在遍历到(c=10, id=30)这一行之后,满足条件的语句已经有两条,循环就结束了。

加锁结果:c=5,id=5)到(c=10,id=30)这个前开后闭区间。

案例八:一个死锁的例子

分析

  1. session A 启动事务后执行查询语句加lock in share mode,在索引c上加了next-key lock(5,10] 和间隙锁(10,15);

  2. session B 的update语句也要在索引c上加next-key lock(5,10] ,进入锁等待;

  3. 然后session A要再插入(8,8,8)这一行,被session B的间隙锁锁住。由于出现了死锁,InnoDB让session B回滚

结论:在分析加锁规则的时候可以用next-key lock来分析。但是要知道,具体执行的时候,是要分成间隙锁和行锁两段来执行的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值