首页 > 其他分享 >Mvcc并发控制

Mvcc并发控制

时间:2023-12-28 21:49:15浏览次数:31  
标签:控制 事务 快照 DB UndoLog .... 并发 Mvcc ID

原理

MVCC 实现主要依赖于数据行的三个隐藏字段、UndoLog、ReadView 来实现的。

首先对于任意一行数据,它都有如下三个隐藏字段:

  • DB_TRX_ID:最近修改的事务ID,记录修改或创建这条记录的最新事务ID;
  • DB_ROW_ID:如果数据没有主键,生成的一个隐藏的默认主键;
  • DB_ROLL_PTR:回滚指针,指向该条记录的上一个版本,需要配合 UndoLog 使用;

UndoLog

UndoLog 是回滚日志,在执行插入、更新、删除操作时会生成相反的 SQL 操作语句并存储到 UndoLog中。如果是插入语句,产生的 UndoLog 可以在事务提交后立刻丢弃,只在回滚时需要;而如果是 更新、删除语句,需要保留 UndoLog,因为不仅在事务回滚时需要,在快照读时也需要,所以不能随便删除。

数据更新或删除时只是更新一下数据行的 delete_bit等位,并不会真正删除这条数据。Mysql会有一个 purge线程来定时清理 delete_bit 为 TRUE 的数据。

假设有一个事务ID为1的事务向表中插入记录,此时的数据状态为:

name age gender DB_ROW_ID DB_TRX_ID DB_ROLL_PTR
zhangsan 23 man 1 1 null

此时有另一个事务对 name 字段修改,修改时会先对这行加排他锁,然后将旧数据拷贝到 UndoLog 日志中作为副本;拷贝完毕后更新这行数据,修改 name 值、DB_TRX_ID 值、DB_ROLL_PTR 指向 UndoLog 日志的副本记录,然后提交事务后释放锁。

所以如果多个事务操作同一行数据,会生成类似于链表的数据行,链头为最新的 UndoLog,链尾为最旧的 UndoLog。

ReadView

Read View 是事务进行快照读时产生的读视图,在该事务执行快照操作时会生成当前系统的快照,记录当前活跃的事务id。利用 Read View 来做可见性判断,能够对比当前数据行的 DB_TRX_IDRead View 中的属性,如果当前数据行不满足可见性条件,就通过 DB_ROLL_PTR 回滚到上一条记录接着判断,直到找到可见性的记录为止。

Read View 包括的三个核心属性如下:

  • trx_list:记录当前正在活跃的事务ID(1,2,3);
  • up_limit_id:记录 trx_list 中最小的事务ID (1);
  • low_limit_idReadView 生成时刻系统尚未分配的事务ID,记录系统将要生成的下一个事务ID(4);

Read View 会按照以下规则去比较 DB_TRX_ID 以找到符合可见性的那条数据:

  • DB_TRX_ID < up_limit_id:说明在最小ID的事务出现前,这条数据就已经提交了,则可以看见;反之继续;
  • DB_TRX_ID >= low_limit_id:只有在生成新的事务后才能看见这条记录,不可见;反之当前 DB_TRX_ID 介于二者之间,需要判断是否在活跃事务ID集合 trx_list 中来决定是否可见;
  • 如果在 trx_list 中,说明事务还未提交不可见;否则可见。

不同隔离级别下的MVCC

RC 隔离级别下

读已提交隔离级别下,每个快照读都会生成并获取到最新的 Read View。实例如下:

事务1 事务2 事务3 事务4
事务开始 事务开始 事务开始
修改并提交 .... ....
快照读 进行中
.... .... 事务开始
.... .... 修改未提交
快照读 .... ....

第一次快照读时,活跃的事务ID为(2,3),up_limit_id 为 (2),low_limit_id 为(4),因此只能读取到事务1的数据,读不到事务4的数据;

第二次快照读时,活跃事务ID为(2,3,4),up_limit_id 为(2),low_limit_id 为(5),但是此时事务4 为活跃事务,所以不可见,仍然只能读到事务1.

RR 隔离级别下

可重复读隔离级别下,在第一次快照读时创建 ReadView,之后每次快照读都用这个 Read View

事务1 事务2 事务3 事务4
事务开始 事务开始 事务开始
修改并提交 .... ....
快照读 进行中
.... .... 事务开始
.... .... 修改未提交
快照读 .... ....

在第一次快照读之后不管额外进行多少次快照读都会使用第一次快照 Read View 数据,活跃事务ID为(2,3),up_limit_id 为 (2),low_limit_id 为 (4).


使用场景

不同隔离级别实现多事务并发控制的方式不同:

  • 读未提交模式:直接返回记录上的最新值,没有试图概念;
  • 读已提交模式:通过 MVCC 在每次执行 SQL 语句时创建视图,同一条记录的多个事务操作会生成多个 UndoLog 日志副本,并按照事务执行顺序以 DB_ROW_PTR 为回滚指针连接起来。当某个事务执每次行读操作时,生成 Read View,依次匹配链表的每个节点直到找到匹配的可见 UndoLog 记录。
  • 可重复读模式:原理同读已提交模式,区别是可重复读只会执行一次快照读,之后的每次读操作都会重复利用第一次快照读的结果。
  • 串行化模式:使用加锁的方式来避免并行访问,使用比较少,并发性低。

可重复读使用场景

比如说两张表,消费记录表和余额表。当在做数据校对时希望能够处理用户新的交易数据但又不影响校对过程。这时可以将隔离级别设置为可重复读。

参考

https://juejin.cn/post/7102676257149550622

标签:控制,事务,快照,DB,UndoLog,....,并发,Mvcc,ID
From: https://www.cnblogs.com/istitches/p/17933627.html

相关文章

  • 快乐学Python,Python基础之如何控制代码执行顺序?【分支结构和循环结构】
    在上一篇文章中,我们所操作的所有代码都是顺序执行的。什么意思呢?就是我们在所有例子中的代码,计算机都是从第一句开始执行,执行完毕后执行第二句,以此类推,最终执行完整个代码块。以下面代码为例:print("FirstLine!")print("SecondLine!")print("ThirdLine!")输出结果:First......
  • linux权限、特殊权限、ACL控制
    Linux基本权限1.权限基本概述1.什么是权限?我们可以把它理解为操作系统对用户能够执行的功能所设立的限制,主要用于约束用户能对系统所做的操作,以及内容访问的范围,或者说,权限是指某个特定的用户具有特定的系统资源使用权力。2.为什么要有权限?因为系统中不可能只存在一个root用......
  • 跟着王洋老师学编程 - 1.7 键盘控制小球
    一、抽象方法/类和接口的定义抽象方法-无法清晰描述的方法,比如动物类的吃方法;抽象类-如果一个类中含有抽象方法,那这个类也必须要定义成抽象类;接口-如果一个类中只有抽象方法,没有属性,这就是一个纯抽象类,即接口。1abstractclassAnimal{//抽象类2pu......
  • 分布式I/O助力医药行业实现高效生产控制
    分布式I/O在医药行业的应用正逐渐受到关注。这种技术为医药制造、包装和检验等环节提供了高效、精确的控制和监测手段,从而确保了产品质量和生产安全。分布式I/O能够提高医药生产的效率。在医药制造过程中,需要严格控制各种工艺参数,如温度、压力、流量和浓度等。分布式I/O可以实时采......
  • Unity3D Shader Compute Shader基于GPU的并发计算详解
    在游戏开发中,计算密集型的任务通常需要耗费大量的CPU资源,这可能导致游戏性能下降,影响玩家的游戏体验。为了解决这个问题,Unity3D引入了ShaderComputeShader技术,它使用GPU进行并发计算,将一些计算密集型任务从CPU转移到GPU上执行,以提高游戏的性能和效率。本文将详细介绍Unity3DSha......
  • Spring IoC(控制反转)、DI(依赖注入)
    1.IoCIoC(InversionofControl,控制反转)面向对象的一种设计思想,很多语言的框架都使用了IoC这个设计思想,并非特属于Spring,其实现为将实例对象交给第三方容器管理,创建实例对象的时候,注入这些实例对象所依赖的实例对象,而不是在内部创建。所谓的内部创建如下所示,连接数据库的DateSour......
  • 控制反转 (IoC)
    在传统的软件设计中,程序的控制流程是由程序本身决定的。这意味着程序定义了各种组件何时以及如何创建、使用和销毁。相比之下,IoC是一种设计原则,它规定将控制从程序转移到外部实体(IoC容器或框架)。在IoC驱动的设计中,组件及其生命周期由IoC容器管理,该容器负责创建、初始化这些......
  • 超时控制:Go语言下的网络请求与时间赛跑
    开场白:在互联网的世界里,我们经常要与各种API打交道。有时,这些API可能会因为各种原因而变得“慢条斯理”,这时,超时控制就显得尤为重要了。今天,我们就来聊聊如何在Go语言中实现HTTP请求的超时控制,与时间赛跑!知识点一:了解超时控制的必要性想象一下,当你正在等待一个重要的API响应时,如果......
  • java进行数据库操作的并发控制的2种方法
    本文分享自华为云社区《java进行数据库操作的并发控制》,作者:张俭。在现代应用编码中,从数据库里面find出来,进行一些业务逻辑操作,最后再save回去。即:Personperson=personRepo.findById(id);person.setAge(18);personRepo.save(person);但是这样的业务操作,如果一个线程修改......
  • Sass控制指令
    目录@if@for@each基本用法高级用法一:同时遍历多个列表高级用法二:遍历拉列表的key和value@while@ifsass中的条件控制指令用法同JavaScript中的if语句用法大致一样。例如:$cond:14px;body{ @if$cond<0px{ @error'thisisavailavle'; }@elseif$cond>100px{ @wa......