vlambda博客
学习文章列表

2020-12-14:mysql中,可重复读是怎么实现的?

福哥答案2020-12-14:


[答案来自此链接:](http://bbs.xiangxueketang.cn/question/735)


快照读:就是select。MVCC。

select * from table ….;


当前读:特殊的读操作,插入/更新/删除操作,属于当前读,处理的都是当前的数据,需要加锁。为了解决当前读中的幻读问题,MySQL事务使用了Next-Key锁。

select * from table where ? lock in share mode;

select * from table where ? for update;

insert;

update ;

delete;


MVCC在MySQL的InnoDB中的实现如下:

在InnoDB中,会在每行数据后添加两个额外的隐藏的值来实现MVCC,这两个值一个记录这行数据何时被创建,另外一个记录这行数据何时过期(或者被删除)。在实际操作中,存储的并不是时间,而是事务的版本号,每开启一个新事务,事务的版本号就会递增。在可重读Repeatable reads事务隔离级别下:

1.SELECT时,读取创建版本号<=当前事务版本号,删除版本号为空或>当前事务版本号。

2.INSERT时,保存当前事务版本号为行的创建版本号。

3.DELETE时,保存当前事务版本号为行的删除版本号。

4.UPDATE时,插入一条新纪录,保存当前事务版本号为行创建版本号,同时保存当前事务版本号到原来删除的行。

通过MVCC,虽然每行记录都需要额外的存储空间,更多的行检查工作以及一些额外的维护工作,但可以减少锁的使用,大多数读操作都不用加锁,读数据操作很简单,性能很好,并且也能保证只会读取到符合标准的行,也只锁住必要行。