写点什么

MySQL-MVCC 与锁机制

用户头像
insight
关注
发布于: 2021 年 03 月 26 日

MVCC

mvcc 是多版本并发控制的缩写,它是行级锁的一个变种,在很多情况下避免了加锁操作。本质上,它是通过版本号机制来保证不同事务间读取的数据不会相互影响。 根据《高性能 MySQL》中的说法,MVCC 在每一行增加了两个隐藏字段,分别是更新时间和删除时间。通过这两个字段,可以决定每一个事务的可见性。具体方式如下:

可见性

每一个事务,只能看到更新时间在自己版本号之前且删除时间为空或在自己版本号之后的数据。

对于每个操作,InnoDB 采用了如下方式来维护 MVCC 机制。

insert

对于插入,InnoDB 会插入一条记录,并将其更新时间更新为当前版本号。

delete

InnoDB 会将当前记录的删除时间更新为当前的版本号。

update

InnoDB 会创建一条新纪录,创建时间为当前版本号,并将原来的记录的删除时间更新为当前版本号。


RR(可重复读)下的加锁原因

可重复读隔离级别解决了可重复读的问题,但是还是无法解决幻读的问题,而幻读的存在,会导致 binlog 进行恢复的时候,数据产生不一致的情况。因此需要给 RR 中的数据加锁,解决幻读的问题。

RR(可重复读)下的加锁原则

  1. 最大的原则:只针对访问到的对象加锁。有索引的时候,在索引上加锁;如果没有索引,就只能在表中加锁。

  2. 加锁的基本单位:next-key lock(临键锁),这是一个左开右闭的锁,本质上是由 间隙锁+行锁 来实现的。

  3. 加锁的范围:查询到的记录的前后,即 (左边第一个不在范围里的值,右边第一个不在范围里的值]

  4. 锁的退化(优化):为了减少加锁带来的阻塞,因此产生了锁的退化机制。有两条退化机制:

  5. 如果是 等值查询+唯一索引 ,那么由唯一索引保证了值的前后不会出现值相同的记录,因此,锁可以退化成行锁

  6. 如果是 等值查询,右边第一个不是该值的记录的变化不会影响查询的结果,因此,右边第一个不满足等值条件的记录的锁,退化成间隙锁


用户头像

insight

关注

不要混淆行动与进展、忙碌与多产。 2018.11.17 加入

永远都是初学者

评论

发布
暂无评论
MySQL-MVCC与锁机制