一、MySQL可重复读级别下,因为MVCC引起的BUG,下图1为相应的Java代码,其中事务1的生命周期最长,循环开启的事务2、3、4。。。与事务1并行 ,数据的读取只会成功一次,后面的读不到新增数据,从而出现空指针异常,但是当事务隔离级别为读提交时,程序会正常执行

                                        图1

解决方案:将方法userRemoteService.addUser和UserBaseContext.getUserBaseByUserId放在两个方法中,避免事务的并发问题

二、MVCC简介:Multiversion Concurrency Control,多版本并发控制机制,行级锁的一个变种, 但是它在很多情况下避免了加锁操作, 因此开销更低,实现了非阻塞的读操作,只在read committed和repeatable read两个隔离级别下工作,因为read uncommitted总是读取最新的数据行,而serializable则会对所有读取的行都加锁

三、数据行隐藏字段

6字节的DATA_TRX_ID 标记了最新更新这条行记录的transaction id,每处理一个事务,其值自动+1

7字节的DATA_ROLL_PTR 指向当前记录项的rollback segment的undo log记录,找之前版本的数据就是通过这个指针

6字节的DB_ROW_ID,当由innodb自动产生聚集索引时,聚集索引包括这个DB_ROW_ID的值,否则聚集索引中不包括这个值.,这个用于索引当中

DELETE BIT位用于标识该记录是否被删除,这里的不是真正的删除数据,而是标志出来的删除。真正意义的删除是在commit的时候

对于有有三个字段id、name、balance的表,其中id为主键,实际的拥有的列如下

图2

四、具体的执行过程:

SELECT:Innodb检查每行数据,确保他们符合两个标准:

1、InnoDB只查找版本早于当前事务版本的数据行(也就是数据行的版本必须小于等于事务的版本),这确保当前事务读取的行都是事务之前已经存在的,或者是由当前事务创建或修改的行

2、行的删除操作的版本一定是未定义的或者大于当前事务的版本号,确定了当前事务开始之前,行没有被删除

符合了以上两点则返回查询结果。

INSERT:InnoDB为每个新增行记录当前系统版本号作为创建ID,该操作没有回滚指针,因为不存在历史版本

DELETE:InnoDB为每个删除行的记录当前系统版本号作为行的删除ID。

UPDATE:InnoDB复制了一行。这个新行的版本号使用了系统版本号。它也把系统版本号作为了删除行的版本

事务执行过程中,只有在第一次真正修改记录时(比如使用INSERT、DELETE、UPDATE语句),才会被分配一个单独的事务id,这个事务id是递增的,下面以update为例说明

begin->用排他锁锁定该行->记录回滚数据到undo log->将修改前的行标记为删除,写事务编号->新增行保存修改后的值,写事务编号,回滚指针指向undo log中的修改前的行->记录修改后数据redo log->commit->后台线程将数据写磁盘

图3

优点:
保存这两个额外系统版本号,使大多数读操作都可以不用加锁。这样设计使得读数据操作很简单,性能很好。

缺点:
每行纪录都需要额外的存储空间,需要做更多的行检查工作,以及一些额外的维护工作。

五、read view

1.判断当前版本数据项是否可见

2.提交读的隔离级别下,事务开始后到结束前,每次读取数据都会生成一个read view,而可重复读的隔离级别,只有事务开始后第一次读取数据,才生成read view

2.在innodb中, 每创建一个新事务, 存储引擎都会将当前系统中的活跃事务列表创建一个副本(read view), 副本中保存的是系统中当前不应该被本事务看到的其他事务id列表

3.当用户在事务中要读取某行记录的时候, innodb会将该行当前的版本号与该read view进行比较

4.比较流程:read view中最早的事务id为tmin,最迟的事务id为tmax,当前事务id为t0

图4

参考文章

https://www.cnblogs.com/williamjie/p/9492810.html
https://www.jianshu.com/p/db334404d909
https://juejin.im/post/5c9b1b7df265da60e21c0b57

MySQL-InnoDB-MVCC多版本并发控制的更多相关文章

  1. mysql的MVCC多版本并发控制机制

    MVCC多版本并发控制机制 全英文名:Multi-Version Concurrency Control MVCC不会通过加锁互斥来保证隔离性,避免频繁的加锁互斥. 而在串行化隔离级别为了保证较高的隔 ...

  2. 针对MySQL的MVCC多版本并发控制的一些总结

    MVCC MVCC细节太多,我直接备忘一下总结: MVCC就是通过事务的ID与行数据的版本(修改事务的ID)进行比较(通过redo log可以回溯版本)得出哪些版本的行数据可见和不可见而实现的事务隔离 ...

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

    概述 为了提高并发MySQL加入了多版本并发控制,它把旧版本记录保存在了共享表空间(undolog),当事务提交之后将重做日志写入磁盘(前提innodb_flush_log_at_trx_commit ...

  4. InnoDB学习(五)之MVCC多版本并发控制

    MVCC多版本并发控制,是一种数据库管理系统并发控制的方法.MVCC多版本并发控制下,数据库中的数据会有多个版本,分别对应不同的事务,从而达到事务之间并发数据的隔离.MVCC最大的优势是读不加锁,读写 ...

  5. MySQL InnoDB MVCC

    MySQL 原理篇 MySQL 索引机制 MySQL 体系结构及存储引擎 MySQL 语句执行过程详解 MySQL 执行计划详解 MySQL InnoDB 缓冲池 MySQL InnoDB 事务 My ...

  6. MVCC多版本并发控制

    MVCC多版本并发控制 爱情小傻蛋关注 82019.09.28 23:23:37字数 4,740阅读 91,421 前提概要 什么是MVCC 什么是当前读和快照读? 当前读,快照读和MVCC的关系 M ...

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

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

  8. MySQL InnoDB MVCC深度分析

    关于MySQL的InnoDB的MVCC原理,很多朋友都能说个大概: 每行记录都含有两个隐藏列,分别是记录的创建时间与删除时间 每次开启事务都会产生一个全局自增ID 在RR隔离级别下 INSERT -& ...

  9. 聊聊MVCC多版本并发控制

    一.介绍 MVCC只在RR和RC 2个隔离级别下才能工作.MySQL的大多数事务存储引擎实现的都不是简单的行级锁机制.基于提升并发性能的考虑,它们一般都同时实现了MVCC. 通俗的来讲,MVCC是行级 ...

  10. MVCC 多版本并发控制

    关于事务的介绍暂且不谈. InnoDB行级锁,虽然在很大程度上提高了事务的并发性,但是终究还是要耗费很大的.为了更进一步的提高并发性同时降低开销,存储引擎会同时实现MVCC. InnoDB实现MVCC ...

随机推荐

  1. Linbux下的Bash对拍

    下面是\(Linux\)下的\(bash\)对拍程序: #!/bin/bash t=0 //数据组数 while true; do let "t=$t + 1" echox pri ...

  2. Java8新特性——新一套时间API的使用

    JDK 1.0中包含了一个java.util.Date类,但是它的大多数方法已经在JDK 1.1引入Calendar类之后被弃用了.而Calendar并不比Date好多少.它们面临的问题是: 可变性: ...

  3. cuda,cudnn

    20191008 服务器上的cuda总是被人搞坏掉,好烦.记录下: 卸载干净cuda sudo rm -rf /usr/local/cuda sudo apt-get remove cuda sudo ...

  4. 下载安装office2019

    Hello,大家好,我是小喵. 支付宝搜索“321994”,领红包喽! 前几天答应给大家写一篇关于安装激活Office2019的文章.一直在准备,准备制作GIF动图,制作图片等,把我电脑上的Offic ...

  5. 练手WPF(一)——模拟时钟与数字时钟的制作(下)

    继续数字时钟.上一篇写好了数字笔划专用的DigitLine类.现在是时候使用它了.下面对一些主要代码进行说明. 打开MainWindow.xaml.cs文件: (1)添加字段变量 // 数字时钟字段定 ...

  6. UML与设计模式

    这个在大中华区不知道是否重视,反正我是接触的人中谈的少,除了想起大学有个博士级别的老师,给我们上课天天老拿着一本外文翻译的UML书外,可真要重视起来的. 加深一个单词,模式pattern,patter ...

  7. 99%的程序都没有考虑的网络异常?使用Fundebug.notify()主动上报

    近日看到一篇文章99%的程序都没有考虑的网络异常,开篇提到: 绝大多数程序只考虑了接口正常工作的场景,而用户在使用我们的产品时遇到的各类异常,全都丢在看似 ok 的 try catch 中.如果没有做 ...

  8. 项目进程中input的onblur事件挂不上去,失效问题解决记录

    一开始直接在js文件中写 var n=document.querySelector("input"); n.onblur=funcition(){ ///事件过程吧啦啦啦 }; 事 ...

  9. django更换ORM连接处理(连接池)转

    1 概述 在使用 Django 进行 Web 开发时, 我们避免不了与数据库打交道. 当并发量低的时候, 不会有任何问题. 但一旦并发量达到一定数量, 就会导致 数据库的连接数会被瞬时占满. 这将导致 ...

  10. 阅读高翔的RGBD-SLAM博文笔记

    目录 高翔的RGBD-SLAM笔记 前端VO: 后端优化 高翔的RGBD-SLAM笔记 RGBD相机的特点: 使用RGBD相机中的深度这一维信息,以及相机的针孔成像模型,相机的内参,可以将二维点恢复成 ...