• 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呢?的更多相关文章

  1. mysql事务原理及MVCC

    mysql事务原理及MVCC 事务是数据库最为重要的机制之一,凡是使用过数据库的人,都了解数据库的事务机制,也对ACID四个 基本特性如数家珍.但是聊起事务或者ACID的底层实现原理,往往言之不详,不 ...

  2. MySQL InnoDB下关于MVCC的一个问题的分析

      这个是网友++C++在群里问的一个关于MySQL的问题,本篇文章实验测试环境为MySQL 5.6.20,事务隔离级别为REPEATABLE-READ ,在演示问题前,我们先准备测试环境.准备一个测 ...

  3. MySQL之UNDO及MVCC、崩溃恢复

      UNDO特性:避免脏读.事务回滚.非阻塞读.MVCC.崩溃恢复 事务工作流程(图2) MVCC原理机制 崩溃恢复:redo前滚.undo回滚 长事务.大事务:危害.判断.处理 UNDO优化:实现u ...

  4. MySQL多版本并发控制(MVCC)

    MVCC是行级锁的一个变种,但是它在很多的情况下避免了加锁操作,因此开销更低.MySQL,包括Oracle.PostgreSQL都实现了MVCC,虽然每个关系数据库实现不一样,但大都是实现了非阻塞的读 ...

  5. java架构之路-(mysql底层原理)Mysql事务隔离与MVCC

    上几篇博客我们大致讲了一下mysql的底层结构,什么B+tree,什么Hash需要回行啊,再就是讲了mysql优化的explain,这次我们来说说mysql的锁. mysql锁 锁从性能上分为乐观锁( ...

  6. MySQL事务隔离之MVCC版本控制

    MVCC简介 MVCC是一种多版本并发控制机制. MVCC是为了解决什么问题? 大多数的MYSQL事务型存储引擎,如,InnoDB,Falcon以及PBXT都不使用一种简单的行锁机制.事实上,他们都和 ...

  7. mysql幻读、MVCC、间隙锁、意向锁(IX\IS)

    IO即性能 顺序主键写性能很高,由于B+树的结构,主键如果是顺序的,则磁盘页的数据会按顺序填充,减少数据移动,随机主键则可能由于记录移动产生很多io 查询二级索引时,会再根据主键id获取数据页,产生一 ...

  8. MySQL多版本并发控制——MVCC机制分析

    MVCC,即多版本并发控制(Multi-Version Concurrency Control)指的是,通过版本链维护一个数据的多个版本,使得读写操作没有冲突,可保证不同事务读写.写读操作并发执行,提 ...

  9. 【Mysql】深入理解 MVCC 多版本并发控制

    MVCC MVCC(Multi-Version Concurrency Control),即多版本并发控制.是 innodb 实现事务并发与回滚的重要功能.锁机制可以控制并发操作,但是其系统开销较大, ...

随机推荐

  1. Java集合--阻塞队列及各种实现的解析

    阻塞队列(Blocking Queue) 一.队列的定义 说的阻塞队列,就先了解下什么是队列,队列也是一种特殊的线性表结构,在线性表的基础上加了一条限制:那就是一端入队列,一端出队列,且需要遵循FIF ...

  2. ShoneSharp语言(S#)的设计和使用介绍系列(6)— 字符串String

    ShoneSharp语言(S#)的设计和使用介绍 系列(6)— 字符串String 作者:Shone 声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/ShoneS ...

  3. 【万字图文-原创】 | 学会Java中的线程池,这一篇也许就够了!

    碎碎念 关于JDK源码相关的文章这已经是第四篇了,原创不易,粉丝从几十人到昨天的666人,真的很感谢之前帮我转发文章的一些朋友们. 从16年开始写技术文章,到现在博客园已经发表了222篇文章,大多数都 ...

  4. PHP SESSION 操作

    Session的声明与使用 Session的设置不同于Cookie,必须先启动,在PHP中必须调用session_start().session_start()函数的语法格式如下: Bool sess ...

  5. 基于 abp vNext 和 .NET Core 开发博客项目 - 使用Redis缓存数据

    上一篇文章(https://www.cnblogs.com/meowv/p/12943699.html)完成了项目的全局异常处理和日志记录. 在日志记录中使用的静态方法有人指出写法不是很优雅,遂优化一 ...

  6. Redis数据迁移同步工具(redis-shake)

    前言 最近线上一台自建redis服务的服务器频繁报警,内存使用率有点高,这是一台配置比较简陋(2C8G)的机子了,近期也打算准备抛弃它了.抛弃之前需对原先的数据进行迁移,全量数据,增量数据都需要考虑, ...

  7. uniapp轻轻松松开发各种类型的小程序

    1.前言 现在移动端用户使用量占据了市场大部分的比例,今天 给大家说说怎么去开发一个小程序,今天使用的是uniapp 2.什么是uniapp uni-app 是一个使用 Vue.js 开发所有前端应用 ...

  8. 枚举&注解

    枚举:自定义枚举类 使用Enum关键字定义的枚举类 注解:jdk内置的基本注解类型(3个) 自定义注解类型 对注解进行注解(元注解4个) 利用反射获取注解信息(反射部分涉及) 自定义枚举类: Test ...

  9. MySQL8离线安装

    现在离线安装包: 登录官网准备下载 https://dev.mysql.com/downloads/mysql/ 2,开始下载 解压安装包: 开始解压: 解压完成: 新建init文件: 在解压目录下创 ...

  10. go语言的主要特征

    go语言主要特征 1.自动立即回收. 2.更丰富的内置类型. 3.函数多返回值. 4.错误处理. 5.匿名函数和闭包. 6.类型和接口. 7.并发编程. 8.反射. 9.语言交互性. golang文件 ...