首页 > 其他分享 >MVVC学习的一点理解

MVVC学习的一点理解

时间:2022-11-05 23:55:16浏览次数:67  
标签:事务 快照 MVVC 学习 Read 理解 版本 MVCC id

MVCC

全名叫做:多并发版本并行(concurrent)控制

是一种并发控制方法

再MySQL InnoDB的实现主要是为了提高数据库并发性能,处理读-写冲突

MVCC知识一个抽象概念,而在MySQL中,快照读就是MySQL实现MVCC模型的一个非阻塞读功能(相对而言,当前读就是悲观锁的具体实现)

当前读和快照读

  • 当前读:加悲观锁

    • select lock in share mode

    • select for update

    • update/insert/delete

  • 快照读

    • 不加锁的select就是快照读,即不加锁的非阻塞读

    • 快照读的实现是基于MVCC(可以认为其是行锁的一个变种,很多情况下避免了加锁操作)

    • 由于是基于多版本,快照读读到的并不一定是数据的最新版本,而有可能是历史版本

MVCC的能解决的问题

数据库并发三种场景

  • 读-读:不需要并发控制

  • 读-写:隔离性问题,脏读,幻读,不可重复读

  • 写-写:可能存在更新丢失问题,需要加悲观锁或者乐观锁

 

MVCC就是用来解决读-写冲突的无锁并发控制

  • 为事务分配单项增长的时间戳,为每个修改保存一个版本

  • 版本与事务时间戳关联,读操作只读事务开始前数据库的快照

  • 可以解决脏读,幻读,不可重复读等读写隔离问题,但是不能解决更新丢失问题(写写隔离)

MVCC的实现原理

其实现大概依赖三部分

  • 3个隐式字段:每一行除了用户自定义的字段外,还有数据库隐式定义的,用来记录事务的时间戳

    • DB_TRX_ID:最近一次修改这条记录的事务ID

    • DB_ROLL_PTR:回滚指针,指向这条记录的上一个版本(指向undo日志里)

    • DB_ROW_ID:隐含的自增id(隐藏逐渐),如果没有主键,InnoDB会自动以这个字段产生一个聚簇索引

  • undo日志:主要分为两种

    • 插入undo日志,事务提交之后就可以丢掉的,因为没有读写冲突,这部分只负责事务回滚

    • update undo日志,包括update和delete,因为有读写冲突,所以还要另外负责处理读写冲突

  • Read View:读视图,其实就是所谓的快照

    • 每个事务在开启的时候都会被分配一个id(自增)

    • 在事务进行快照读的时候产生Read View,记录并维护系统当前活跃事务的id

    • Read View主要是用来做可见性判断的,执行快照读的时候来判断当前事务能看到哪个版本的数据,有可能是最新版本,也有可能是undo log中某个旧版本

    • 维护四个内容

      • id_list生成快照时,系统中活跃的事务id列表

      • m_trx_id:当前活跃事务最小的id

      • max_trx_id:下一个将要分配的事务id

      • creator_trx_id:声称该ReadView事务的事务id

 

 

第一次快照读某个数据的时候生成Read View(快照),然后之后每次再读取这行数据的时候,都会根据之前生成的这个快照来判断版本号,确定哪个版本是可读的,哪个版本是不可读的

 

当某个事务想要读取某一行数据时,MVCC判断哪个版本对当前事务是可见的过程:

  • 从版本链开始获取记录,记为id(查每行记录的DB_TRX_ID,看最后一次修改这行数据的事务)

  • 如果这个id==creator_trx_id,说明上一次修改是本事务,可以直接读取

  • 如果这个id<min_trx_id,说明上一次修改这行数据的事务已经被提交了(或者说成生成这个版本的时间在生成快照之前),这个版本可以被当前事务访问

  • 如果这个id>=max_trx_id,说明上一次修改这行数据的事务在生成Read View之后才开启,这个版本不可以被当前事务访问(否则会造成不可重复读),需要根据链表指针,找到下一个版本,重复这个步骤

  • 最后还要查一下是否在活跃事务列表里(因为这个事务可能加载一大一小之前,但是很早之前就commit了,生成快照的时候不活跃,和<min_trx_id的情况是一样的),如果在列表里,说明这个版本是不可访问的,因为这是其他事务未提交的数据

 

附一张流程图吧

 

总结一下,事实上快照就相当于记录了一下快照读时各个事务的状态,记录了两个边界情况和一个活跃队列,目的都是为了定位后面读取时的版本号和当前事务的相对时间关系,而版本号的表示是通过最后一次修改该行的事务id和它之后的那条链表

  • 如果在生成快照的时候已经提交了,当然没问题,这包括两种情况,小于最小id和不在活跃队列中都是这个情况(我认为最小id是为了减小检查这个list的次数)

  • 如果在生成快照的时候还未提交(查版本号找到的最近一次修改该行的事务id发现的),就需要查找undo log上一条记录,直到查找到合适读的版本号

 

再加一点:

MVVC是用来解决读写隔离的,读写隔离有四个等级,串行化是使用了行锁,读取未提交没有做读写隔离

  • read-committed:每次读取的时候都生成Read View,所以可能导致不可重复读

  • repeatable read:每次读取都根据第一次快照读的Read View,所以每次都是读取到同一个版本号

 

参考自:https://blog.csdn.net/zzti_erlie/article/details/110454543?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166761746016800182734227%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166761746016800182734227&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-2-110454543-null-null.142^v63^opensearch_v2,201^v3^control_2,213^v1^control&utm_term=MVCC&spm=1018.2226.3001.4187

标签:事务,快照,MVVC,学习,Read,理解,版本,MVCC,id
From: https://www.cnblogs.com/mumayiren/p/16861738.html

相关文章

  • 课程学习内容
    一、创建文件的三种方法第一种 @Testpublicvoidcreate1(){StringfilePath="D:\\file1.txt";Filefile=newFile(filePath);try{file.createNewFile();......
  • JAVA学习DAY1
    JAVA学习Windos快捷键ctrl+c:复制Ctrl+v:粘贴ctrl+A:全选ctrl+x:剪切ctrl+Z:撤销Ctrl+s:保存win+R:命令窗口win+shift+esc:任务管理器win+e:打开我的电脑shi......
  • 学习笔记
    创建文件的三种方法//方式1@Testpublicvoidcreate1(){StringfilePath="D:\\file1.txt";Filefile=newFile(filePath);try{file.createNewFile();System.......
  • 2022-2023-1 20221425 《计算机基础与程序设计》第十周学习总结
    学期(如2022-2023-1)学号(如:20221425)《计算机基础与程序设计》第十周学习总结作业信息这个作业属于哪个课程<班级的链接>(如2022-2023-1-计算机基础与程序设计)这......
  • docker实战学习2022版本(五)之DockFile入门实战
    DockFile:DockFile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。官网:https://docs.docker.com/engine/reference/builder/构建三部曲:编写d......
  • 第二篇Typora学习
    学习java第一次使用Typora做笔记Hello,World(两边加2个*号就变成粗体了)Hello,World(两边加1个*号就变成粗体了)Hello,World!(两边加3个*号就变成斜体加粗了)Hello,World!(......
  • 2022-2023-1 20221306 《计算机基础和程序设计》第十周学习总结
    作业信息这个作业属于那个班级 https://edu.cnblogs.com/campus/besti/2022-2023-1-CFAP作业要求 https://www.cnblogs.com/rocedu/p/9577842.html#WEEK10作业目标学习......
  • 大三上学期学习日记7
    这周完成了老年人评估系统的界面管理设计    ......
  • const_iterator学习
    转自:https://www.cnblogs.com/greatverve/archive/2012/09/12/const-iterator.html1.介绍如果传递过来一个const类型的容器,那么只能用const_iterator来遍历。 voidMe......
  • 学习创业计划的意义
    创业计划书是一份全方位的商业计划,其主要用途是递交给投资商,以便于他们能对企业或项目做出评判,从而使企业获得融资。(一)创业计划:学习目标了解创业计划的内容和基本结构;掌握......