聊聊Mysql的MVCC

1 什么是MVCC?

MVCC,是Multiversion Concurrency Control的缩写,翻译过来是多版本并发控制 ,和数据库锁一样,他也是一种并发控制的解决方案。
我们知道,在数据库中,对数据的操作主要有2种,分别是读和写,而在并发场景下,就可能出现以下三种情况:
读-读并发
读-写并发
写-写并发
我们都知道,在没有写的情况下读-读并发是不会出现问题的,而写-写并发这种情况比较常用的就是通过加锁的方式实现。那么,读-写并发则可以通过MVCC的机制解决。

快照读和当前读

在介绍MVCC前,我们先说一下什么是快照读和当前读

快照读

简单的select(不加锁)就是快照读,快照读,读取的是记录数据的可见版本,有可能是历史数据, 不加锁,是非阻塞读。
不同的隔离级别,同一事物中的快照读不一样
• Read Committed:每次select,都生成一个快照读。
• Repeatable Read:开启事务后第一个select语句才是快照读的地方,之后的select读取的数据和第一次一样(和后面生成readview有关),看到后面的readview就理解了。
• Serializable:快照读会退化为当前读

当前读

读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加 锁。对于我们日常的操作,如:select ... lock in share mode(共享锁),select ...
for update、update、insert、delete(排他锁)都是一种当前读。

隐藏字段

当我们创建了一张表,有自己创建的字段,实际上除了这自己创建的字段以外,InnoDB还会自动的给我们添加三个隐藏字段及其含义分别是:

而上述的前两个字段是肯定会添加的, 是否添加最后一个字段DB_ROW_ID,得看当前表有没有主键,如果有主键,则不会添加该隐藏字段。

undolog

回滚日志,在insert、update、delete的时候产生的便于数据回滚的日志。
当insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除。
而update、delete的时候,产生的undo log日志不仅在回滚时需要,在快照读时也需要,不会立即
被删除。
回滚日志就是一条条数据(版本)组成的版本链,每一次记录变更之前都会先存储一份快照到undo log中,那么这几个隐式字段也会跟着记录一起保存在undo log中,就这样,每一个快照中都有一个db trx id字段表示了对这个记录做了最新一次修改的事务的ID以及一个db roll ptr字段指向了上一个快照的地址。(db trx id和db roll ptr是重点,后面还会用到)

readview

ReadView(读视图)是快照读 SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务 (未提交的)id。
ReadView中包含了四个核心字段:


而在readview中就规定了版本链数据的访问规则:
trx_id 代表当前undolog版本链对应事务ID。

流程如下:

不同的隔离级别,生成ReadView的时机不同:
READ COMMITTED :在事务中每一次执行快照读时生成ReadView。
REPEATABLE READ:仅在事务中第一次执行快照读时生成ReadView,后续复用该ReadView。

相关推荐
Python私教2 小时前
model中能定义字段声明不存储到数据库吗
数据库·oracle
mqiqe4 小时前
Python MySQL通过Binlog 获取变更记录 恢复数据
开发语言·python·mysql
工业甲酰苯胺5 小时前
MySQL 主从复制之多线程复制
android·mysql·adb
BestandW1shEs5 小时前
谈谈Mysql的常见基础问题
数据库·mysql
重生之Java开发工程师5 小时前
MySQL中的CAST类型转换函数
数据库·sql·mysql
教练、我想打篮球5 小时前
66 mysql 的 表自增长锁
数据库·mysql
Ljw...5 小时前
表的操作(MySQL)
数据库·mysql·表的操作
哥谭居民00015 小时前
MySQL的权限管理机制--授权表
数据库
wqq_9922502775 小时前
ssm旅游推荐系统的设计与开发
数据库·旅游