什么是MVCC

指维护一个数据的多个版本,使得读写操作没有冲突, 具体实现就是

快照读, 快照读为MySQL实现MVCC提供了一个非阻塞读功能

组成

MVCC的具体实现,还需要依赖于数据库记录中的隐式字段、undo

log日志、readView

image-ggzi.png

image-w5bv.png

MVCC 的实现原理

MVCC的具体实现,依赖于数据库记录中的隐式字段(最近更新的事务id和回滚指针)、undo log日志、readView。

在内部实现中,InnoDB 通过数据行的 DB_TRX_ID(最近更新的事务id) 和 Read View 来判断数据的可见性,如不可见,则通过数据行的DB_ROLL_PTR(回滚指针) 找到 undo log 版本链中的历史版本。这就是快照读每个事务读到的数据版本可能是不一样的,在同一个事务中,用户只能看到该事务创建 Read View 之前已经提交的修改和该事务本身做的修改

ReadView是什么

Read View是MVCC中用来判断数据的可见性的, 里面记录了活跃事务 id 列表, 全局事务中最大的事务 id 值, 创建该 Read View 的事务

的事务 id等.通过比较当前事务id和ReadView中记录的事务id, 就能知道该版本的记录对当前事务是否可见. 如不可见,则通过数据行的DB_ROLL_PTR(回滚指针) 找到 undo log 版本链中的历史版本。这就是快照读

当前读与快照读

当前读: 读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁

对于我们日常的操作,如:select...lock in share mode(共享锁),select...for update、update、insert、delete(排他锁)都

是一种当前读

当前读: 使用临键锁进行加锁来保证不出现幻读

快照读: 不加锁的select就是快照读,快照读读取的是记录数据的可

见版本有可能是历史数据,不加锁

读已提交: 每次select都会生成一个快照读

可重复读: 事务开始后的第一个select才是快照读的地方

串行化: 快照度会退化为当前读

快照读 :由 MVCC 机制来保证不出现幻读