【MySQL】究竟什么是MVCC呢?
- MVCC是什么呢?
MVCC其实就是一个多版本并发控制,即多个不同版本的数据实现并发控制的技术,其基本思想是为每次事务生成一个新版本的数据,
在读数据时选择不同版本的数据即可以实现对事务结果的完整性读取。
- MVCC主要有什么作用呢?
提高并发读写性能,操作时会生成事务id
1》每条记录都会保存两个隐藏列:【trx_id】(事务id)和roll_pointer(回滚指针
2》每次操作都会生成一条undo_log日志,回滚指针指向前一条记录
查询的时候会读取出【read-view】:[未提交的事务id]数组+最大事务id,并根据read-view从undo_log日志中最新的记录一次往下找,查找规则如下:
①从最新记录开始查找:
如果当前记录:事务id < 未提交事务的最小id,则可读
如果当前记录:最小id <= 事务id <= 事务的最小id,则判断事务id是否在未提交事务id的数组中,若在则不可读(如果只有自己还是可读)
如果当前记录:事务id > 事务的最大id,则不可读
②可重复读返回的是第一次查询生成的【read-view】,读已提交每次都会重新生成一个新的【read-view】
MVCC只能实现读已提交和可重复读;如果是读未提交,那么每次查询都能获取最新的修改值。
- Don‘t BB,看个案例先回顾一下事物的隔离级别:
那么事务A在提交前后,事务B读取到的x值是什么样的呢?答案是:事务B在不同隔离级别下,读取到的值不一样。
1》如果隔离级别是读未提交(Read-Uncommited),两次读到的数据都是20,(个人理解读未提交,就是事务A未提交的修改都可以读到)
2》如果隔离级别是读已提交(Read-Committed),第一次读取到的数据是10,第二次读取到的数据是20(我个人理解读已提交,就是只有事务A已提交的修改才可以读到)
3》如果隔离级别是可重复度(Repeatable-Read),两次读到的数据都是20(我个人有理解,读已提交就是事务B有一个很强的隔离性,只要在同一事务内,读到的数据都是相同的)
当执行查询SQL时,会生成一致性视图叫【read-view】,它由执行查询时所未提交事务id数组(数组里最小的事务id为【min_id】和已创建的最大事务id为【max_id】组成),
查询的数据结果要跟【read-view】做比较,从而得到快照结果。话不多少,直接上个案例:
事务1 | 事务2 | 事务3 | 事务4 |
update table set name = 'A' where id = 1 | |||
update table set name = 'B' where id = 1 | |||
commit | update table set name = 'C' where id = 1 | ||
update table set name = 'C' where id = 1 | select name from table where id = 1 ; read-view:[1,3] 3 | ||
commit | |||
commit | select name from table where id = 1 |
Undo日志如下:
事务4在第一次查询过程是这样:
》先比对【undo_log①】,事务id为1,read-view为[,] ,不符合条件,继续向下比对;
》比对【undo_log②】,事务id为3,事务id > 事务的最大id,所以也不可读;
》比对【undo_log③】,事务id为2,最小id <= 事务id <= 事务的最小id,并且不在未提交事务id数组中,所以可以,所以查询出来的【name = B】;
我们可以根据表格看出,事务2已提交,所以结果就应该B,正确。
- 读已提交是如何使用【MVCC】实现的呢?
每次查询的时候生成一个新的【read-view】,然后去【undo】日志中寻找符合结果的一条数据。
所以事务4对应的【read-view】应该为:[1] 3,第二次查询【name = 'C'】
- 可重复读是如何使用【MVCC】实现的呢?
因为每次查询的时候都会生成一个新的【read-view】,但是如果是可重复读的时候,
第一次查询的时候生成一个【read-view】,后面查询的时候便会复用第一次的【read-view】,然后找出一个可读的数据
所以事务4对应的【read-view】应该为:[1,3] 3,第二次查询【name = 'B'】
- 不过可串行化又是如何实现的呢?
串行化会在读取的每一行数据上都加锁(这个意思是部分锁,但不会锁表)
串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
【MySQL】究竟什么是MVCC呢?的更多相关文章
- mysql事务原理及MVCC
mysql事务原理及MVCC 事务是数据库最为重要的机制之一,凡是使用过数据库的人,都了解数据库的事务机制,也对ACID四个 基本特性如数家珍.但是聊起事务或者ACID的底层实现原理,往往言之不详,不 ...
- MySQL InnoDB下关于MVCC的一个问题的分析
这个是网友++C++在群里问的一个关于MySQL的问题,本篇文章实验测试环境为MySQL 5.6.20,事务隔离级别为REPEATABLE-READ ,在演示问题前,我们先准备测试环境.准备一个测 ...
- MySQL之UNDO及MVCC、崩溃恢复
UNDO特性:避免脏读.事务回滚.非阻塞读.MVCC.崩溃恢复 事务工作流程(图2) MVCC原理机制 崩溃恢复:redo前滚.undo回滚 长事务.大事务:危害.判断.处理 UNDO优化:实现u ...
- MySQL多版本并发控制(MVCC)
MVCC是行级锁的一个变种,但是它在很多的情况下避免了加锁操作,因此开销更低.MySQL,包括Oracle.PostgreSQL都实现了MVCC,虽然每个关系数据库实现不一样,但大都是实现了非阻塞的读 ...
- java架构之路-(mysql底层原理)Mysql事务隔离与MVCC
上几篇博客我们大致讲了一下mysql的底层结构,什么B+tree,什么Hash需要回行啊,再就是讲了mysql优化的explain,这次我们来说说mysql的锁. mysql锁 锁从性能上分为乐观锁( ...
- MySQL事务隔离之MVCC版本控制
MVCC简介 MVCC是一种多版本并发控制机制. MVCC是为了解决什么问题? 大多数的MYSQL事务型存储引擎,如,InnoDB,Falcon以及PBXT都不使用一种简单的行锁机制.事实上,他们都和 ...
- mysql幻读、MVCC、间隙锁、意向锁(IX\IS)
IO即性能 顺序主键写性能很高,由于B+树的结构,主键如果是顺序的,则磁盘页的数据会按顺序填充,减少数据移动,随机主键则可能由于记录移动产生很多io 查询二级索引时,会再根据主键id获取数据页,产生一 ...
- MySQL多版本并发控制——MVCC机制分析
MVCC,即多版本并发控制(Multi-Version Concurrency Control)指的是,通过版本链维护一个数据的多个版本,使得读写操作没有冲突,可保证不同事务读写.写读操作并发执行,提 ...
- 【Mysql】深入理解 MVCC 多版本并发控制
MVCC MVCC(Multi-Version Concurrency Control),即多版本并发控制.是 innodb 实现事务并发与回滚的重要功能.锁机制可以控制并发操作,但是其系统开销较大, ...
随机推荐
- mysql小白系列_05 日常操作
mysql启动/关闭 my.cnf的调用顺序 [root@docker02 bin]# ./mysql --help Default options are read from the followi ...
- 如何覆盖elementUI样式
question: 在某个组件里面更改element-Ui的样式,而不影响全局. solution: 在需要更改的组件里新增一个style标签[重点:不要加scoped],然后直接获取class设置样 ...
- 母牛的故事(hdu2018)——笔记待完善
思考:这道题考验的是罗辑思维,这个网址http://blog.csdn.net/sxhelijian/article/details/42609353的罗辑思维值得学习 #include<std ...
- 容器技术之Docker数据卷
前一篇随笔中我们了解了docker的网络相关说明,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/12952616.html:今天我们来聊一聊docker的数据管 ...
- 微软:正式发布针对 .NET Core的 Winform 设计器
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://devblogs.microsoft.com/dotnet/windows-for ...
- [Objective-C] 010_Foundation框架之NSSet与NSMutableSet
在Cocoa Foundation中的NSSet和NSMutableSet ,和NSArray功能性质一样,用于存储对象属于集合.但是NSSet和NSMutableSet是无序的, 保证数据的唯一性, ...
- Linux 任务后台运行软件【即:终端复用器】之---screen
会话: 命令行的典型使用方式是,打开一个终端窗口(terminal window,以下简称"窗口"),在里面输入命令. 用户与计算机的这种临时的交互,称为一次"会话&qu ...
- 日期类之SimpleDateFormat
1.System 类下的currentTimeMillis();2.Date类:java.util.Date及其子类java.sql.Date 如何创建实例:其下的方 ...
- DataFrame迭代过程中多行修改
方法1:df.loc[conditions]=row.values,逐行地进行整行替换 for row in df.iterrows(): row['given_amount']=row['amoun ...
- PHP常量和数据类型
引言 先用一个题来作为开端:PHP字符串的三种定义方式是什么?有什么区别? 它们分别是单引号'',双引号"",newdoc和heredoc. 区别是:单引号不能解析变量,不能解析转 ...