一、非锁定读
在此之前,先了解一个概念,就是非锁定读,也叫快照读。
非锁定读是指InnoDB存储引擎通过多版本控制来读取当前数据库中行的数据,如果读取的行此时正在执行DELETE或UPDATE操作,这时读取操作不会因此等待行上锁的释放,相反,InnoDB存储引擎回去读取行的一个快照数据(快照数据是指该行的之前版本的数据,是通过undo段来实现的,而且undo段用于事务的回滚,所以快照数据本身没有额外的开销)。非锁定读极大地提高了并发性,这是InnoDB存储引擎默认的读取方式,即读取不会占用和等待锁。
二、什么是MVCC?
一个行记录可能不止一个快照数据,这种使用快照数据带来的并发控制,称为MVCC(Multi Version Concurrency Control 多版本并发控制)。在事务隔离级别读已提交(READ COMMITED)和可重复读(REPEATABLE READ)下,InnoDB存储引擎会通过MVCC机制来进行非锁定读。
三、MVCC的实现原理
先直接给出结论:是通过undo log版本链+Read View来实现的。
那什么是undo log版本链和Read View呢,请继续往下看
3.1 undo log版本链
undo log版本链是通过undo log,以链的形式来记录数据的变化,如下图
文章图片
其中trx_id代表该数据版本的事务id,roll_pointer指向上一个数据版本的地址。
3.2 Read View
【【Mysql】MVCC介绍及其实现原理】Read View直接翻译过来就是读视图,它是一个数据结构,包含了4个字段:
- m_ids:当前活跃的事务编号集合
- min_trx_id:最小活跃事务编号
- max_trx_id:预分配事务编号,当前最大事务编号+1
- creator_trx_id:ReadView创建者的事务编号
文章图片
以事务D的第一个Read View为例,当前trx_id为3
- 判断trx_id与Read View的creator_trx_id是否相等,如果相等说明是同一个事务,那么是可读的,否则继续往下判断
- 判断trx_id与min_trx_id比较,如果比min_trx_id小,说明该数据是被Read View创建前提交的事务所修改,那么是可读的,否则继续往下判断
- 判断trx_id与max_trx_id比较,如果比max_trx_id大,说明该数据是被Read View创建后提交的事务所修改,那么是不可读的,否则继续往下判断
- 判断trx_id是否在m_ids里面,如果是,说明事务还未提交,为不可读,否则说明事务已提交,是可读的。
- 当事务D的隔离级别为读已提交时:第一个select查询语句查询到的name为”测试1”,第二个select查询语句查询到的name为”测试2”
- 当事务D的隔离级别为可重复读时:第一个select查询语句查询到的name为”测试1”,第二个select查询语句查询到的name依然为”测试1”
推荐阅读
- 浅入浅出 MySQL 索引
- 如何在Electron Framework中连接到MySQL数据库
- 如何在MySQL中搜索并将”http”替换为”https”
- 如何在Windows的XAMPP中使用cmd提示符导入mysql数据库
- 如何解决Xampp MySQL错误#2002-无法建立连接,因为目标计算机主动拒绝了它
- 如何在MySQL中反转/翻转TinyInt或Boolean列的值
- 如何在Windows上使用XAMPP恢复InnoDB MySQL文件
- 如何使用命令行创建MySQL数据库并为用户设置权限
- 如何从命令行更改MySQL用户的密码