MVCC的实现原理

简介

MVCC(Multi-Version Concurrency Control)即多版本并发控制。

MVCC的实现原理

我们在了解MVCC之前,首先先了解一下几个比较常见的锁。

**读锁:**也叫共享锁、S锁,若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S 锁。这保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。

**写锁:**又称排他锁、X锁。若事务T对数据对象A加上X锁,事务T可以读A也可以修改A,其他事务不能再对A加任何锁,直到T释放A上的锁。这保证了其他事务在T释放A上的锁之前不能再读取和修改A。

**表锁:**操作对象是数据表。Mysql大多数锁策略都支持,是系统开销最低但并发性最低的一个锁策略。事务t对整个表加读锁,则其他事务可读不可写,若加写锁,则其他事务增删改都不行。

**行级锁:**操作对象是数据表中的一行。是MVCC技术用的比较多的。行级锁对系统开销较大,但处理高并发较好。

MVCC使得大部分支持行锁的事务引擎,不再单纯的使用行锁来进行数据库的并发控制,取而代之的是把数据库的行锁与行的多个版本结合起来,只需要很小的开销,就可以实现非锁定读,从而大大提高数据库系统的并发性能。

MVCC工作过程

InnoDB的MVCC,是通过在每行纪录后面保存两个隐藏的列来实现的。这两个列,一个保存了行的创建版本号,一个保存了行的删除版本号。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行纪录的版本号进行比较。在REPEATABLE READ隔离级别下,MVCC具体的操作如下:

undo log

在不考虑redo log 的情况下利用undo log工作的简化过程为:

1)为了保证数据的持久性数据要在事务提交之前持久化

2)undo log的持久化必须在在数据持久化之前,这样才能保证系统崩溃时,可以用undo log来回滚事务

Innodb中的隐藏列

Innodb通过undo log保存了已更改行的旧版本的信息的快照。

InnoDB的内部实现中为每一行数据增加了三个隐藏列用于实现MVCC。

SELECT

InnoDB会根据以下两个条件检查每行纪录:

  1. InnoDB只查找版本早于当前事务版本的数据行,即,行的系统版本号小于或等于事务的系统版本号,这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的。
  2. 行的删除版本,要么未定义,要么大于当前事务版本号。这样可以确保事务读取到的行,在事务开始之前未被删除。

只有符合上述两个条件的纪录,才能作为查询结果返回。

INSERT

InnoDB为插入的每一行保存当前系统版本号作为行版本号。

DELETE

InnoDB为删除的每一行保存当前系统版本号作为行删除标识。

UPDATE

InnoDB为插入一行新纪录,保存当前系统版本号作为行版本号,同时,保存当前系统版本号到原来的行作为行删除标识。

https://www.jianshu.com/p/8845ddca3b23

一文理解Mysql MVCC - 知乎 (zhihu.com)

深入理解 MySQL 的 MVCC 机制 - 云+社区 - 腾讯云 (tencent.com)

全网最全的一篇数据库MVCC详解,不全我负责-mysql教程-PHP中文网

https://blog.csdn.net/u010002184/article/details/88526708 三个日志

MVCC优缺点

MVCC在大多数情况下代替了行锁,实现了对读的非阻塞,读不加锁,读写不冲突。缺点是每行记录都需要额外的存储空间,需要做更多的行维护和检查工作。

补充:

1.MVCC手段只适用于Msyql隔离级别中的读已提交(Read committed)和可重复读(Repeatable Read)。

2.Read uncimmitted由于存在脏读,即能读到未提交事务的数据行,所以不适用MVCC.

原因是MVCC的创建版本和删除版本只要在事务提交后才会产生。

3.串行化由于是会对所涉及到的表加锁,并非行锁,自然也就不存在行的版本控制问题。

4.通过以上总结,可知,MVCC主要作用于事务性的,有行锁控制的数据库模型。

对MVCC的了解就先说这些(未完待续),后面会有对read view介绍。

相关推荐
高山上有一只小老虎25 分钟前
java 正则表达式大全
java·正则表达式
_院长大人_1 小时前
设计模式-工厂模式
java·开发语言·设计模式
MATLAB代码顾问1 小时前
MATLAB实现决策树数值预测
开发语言·决策树·matlab
凌波粒2 小时前
MyBatis完整教程IDEA版(2)--ResultMap/注解/一对多/多对一/lombok/log4j
java·intellij-idea·mybatis
蓝-萧2 小时前
【玩转全栈】----Django基本配置和介绍
java·后端
priority_key2 小时前
排序算法:堆排序、快速排序、归并排序
java·后端·算法·排序算法·归并排序·堆排序·快速排序
韩立学长2 小时前
基于Springboot的旧时月历史论坛4099k6s9(程序、源码、数据库、调试部署方案及开发环境)系统界面展示及获取方式置于文档末尾,可供参考。
数据库·spring boot·后端
不染尘.2 小时前
2025_11_7_刷题
开发语言·c++·vscode·算法
似水এ᭄往昔3 小时前
【C++】--stack和queue
开发语言·c++
TDengine (老段)3 小时前
TDengine 字符串函数 CONCAT_WS 用户手册
android·大数据·数据库·时序数据库·tdengine·涛思数据