首页 > 其他分享 >MVCC 实现原理

MVCC 实现原理

时间:2024-11-23 17:34:44浏览次数:8  
标签:事务 log 实现 undo trx 版本 MVCC 原理 id

  概念

  MVCC是InnoDB用于多版本并发控制,数据库通过它能够做到遇到并发读写的时候,在不加锁的前提下实现安全的并发读操作,是一种乐观锁的实现方式,能大大提高数据库的并发性能,还可以解决脏读,不可重复读的事务隔离问题。

  生效的隔离级别

  MVCC只在读已提交(Read Committed)和可重复读(Repeatable Read)两个事务隔离级别下有效

tips:“读未提交”和“串行化”有视图概念吗?

  1. “读未提交”隔离级别下直接返回记录上的最新值,没有视图概念。

  2. “串行化”隔离级别下直接用加锁的方式来避免并行访问,也没有视图概念。

  实现原理

  主要是依赖行记录中的两个隐式字段 undo log中的版本链ReadView 来实现的。

    两个隐式字段
  1. 在InnoDB中,每行数据都会被添加3个字段

    1. DB_TRX_ID :插入或更新行的最新一个事务ID. (解读:用于MVCC的ReadView判断事务id) 此外, 删除在内部被视为更新,其中行中的一个特殊位被设置为将其标记为已删除.

    2. DB_ROLL_PTR:回滚指针. (解读:用于MVCC中指向undo log记录) 指向已写入回滚段(rollback segment)的一条undo log记录, 记录着行(row)更新前的副本.

    3. DB_ROW_ID:隐藏的自增 ID. (解读:对于MVCC可忽略该字段) 如果InnoDB自动生成聚集索引, 则索引包含这个行ID值. 否则, DB_ROW_ID列不会出现在任何索引中.

    Undo log版本链
  • insert undo log insert undo log是指在insert操作中产生的undo log, 仅用于事务回滚. 因为insert操作的记录, 只对事务本身可见, 对其它事务不可见, 所以该日志可以在事务commit后直接删除. 不需要进行purge(后台清除线程)操作。

  • update undo log update undo log是对delete和update操作产生的的undo log. 该undo log除了用于事务回滚,可能还需要提供MVCC机制, 因此不能在事务commit后就进行删除. 提交时放入undo log链表,等待purge线程(后台清除线程)进行最后的删除。

      每次对记录进行改动,都会记录一条undo日志,就算是该记录的一个旧版本,这条undo log日志包括数据行旧值、roll_pointer(回滚指针 , insert操作对应的undo日志没有该属性,因为该记录并没有更早的版本)、trx_id(事务id)。随着更新次数的增多,回滚指针可以将这些undo日志都连起来,串成一个链表,链表称之为版本链,版本链的头节点就是当前记录最新的undo版本。

    ReadView

      ReadView也叫一致性读视图。

      创建时机
  1. 在“可重复读”隔离级别下,整个事务存在期间都用这个视图。

    1. begin/start transaction命令下,ReadView是在事务启动时创建的(或者说是在执行第一个普通的select语句(快照读)时创建的)

    2. start transaction with consistent snapshot命令下,ReadView是在执行这个命令时立即创建的。

  2. 在“读提交”隔离级别下,每次执行普通的select语句时都会生成一个独立的ReadView

      判断可见性&查找版本链

      MVCC在普通的select语句时才生效。当执行普通的select语句时, ReadView中包含如下4个字段并根据如下规则判断undo log版本链中的哪个版本对当前事务是可见的。如果某个版本的数据对当前事务不可见的话,那就顺着版本链往前找到上一个版本的数据,继续按照如下规则判断可见性,依此类推,直到版本链中的最后一个版本。如果最后一个版本也不可见的话,那么就意味着该条记录对该事务完全不可见,查询结果就不包含该记录。

字段

mysql原始字段

含义

可见性

可见性结论说明

备注

max_trx_id

m_low_limit_id

高水位,应该分配给下一个事务的id 值

>=它的,都不可见

trx_id >= max_trx_id:如果trx_id 值小于 Read View 中的 min_trx_id ,表示这个版本的记录是在创建 Read View 才启动的事务生成的,所以该版本的记录对当前事务不可见

活跃事务:开启但未提交的事务

min_trx_id

m_up_limit_id

低水位,活跃事务最小事务id

<它的,都可见

trx_id < min_trx_id:如果 trx_id 值小于 Read View 中的 min_trx_id ,表示这个版本的记录是在创建 Read View 已经提交的事务生成的,所以该版本的记录对当前事务可见

creator_trx_id

m_creator_trx_id

创建readview的事务id

=它的,都可见

trx_id = creator_trx_id:如果 trx_id 值等于创建Read View的事务Id,那么数据记录的最后一次操作的事务就是当前事务,该版本的记录对当前事务可见

只有在对表中的记录做改动时(执行INSERT、DELETE、UPDATE这些语句时)才会 为事务分配事务id,否则在一个只读事务中的事务id值都默认为0

m_ids

m_ids

创建readview时活跃事务的id列表

当min_trx_id <= trx_id < max_trx_id时,在它里面的不可见,否则可见

  1. min_trx_id <= trx_id < max_trx_id:判断 trx_id 是不是在当前事务ID列表(m_ids)里面

    1. 如果在m_ids中,则代表Read View生成时刻,这个事务还在活跃,还没有Commit,版本记录在前事务不可见

    2. 如果不在m_ids中,则说明,这个事务在Read View生成之前就已经Commit了,版本记录在前事务可见

MVCC如何实现读已提交和可重复度隔离级别

根据上面所述,MVCC可以通过行记录的2个隐式字段、undo log版本链、ReadView生成时机以及判断可见性规则保证不同时刻启动的事务readview之间互不影响,从而实现了已提交和可重复度隔离级别。

标签:事务,log,实现,undo,trx,版本,MVCC,原理,id
From: https://blog.csdn.net/aofeng9/article/details/143919373

相关文章

  • 基于Python校园舆情管理系统设计与实现毕业设计项目
    基于Python校园舆情管理系统设计与实现毕业设计项目大家好,我是俊星学长,一名在Java圈辛勤劳作的码农。今日,要和大家分享的是一款基于Python校园舆情管理系统设计与实现毕业设计项目。项目源码以及部署相关事宜,请联系小村学长,文末会附上联系信息哦。......
  • 项目解决方案:通过视频监控综合资源管理平台实现夜市可视化管理建设解决方案
    目录一.项目背景1.1相关背景描述1.2具体需求分析二.建设目标和设计依据2.1建设目标2.2设计依据三.系统设计和实现3.1方案设计3.2改造和组网说明3.2.1改造说明3.2.2组网说明四.产品简介4.1设备接入4.1.1非国标设备的接入4.1.2国标设备的接入4.2设备管理4.3权限......
  • C++实现Raft算法
    概念部分Raft算法是一种用于实现分布式系统中的一致性的算法。它是为了容易理解而设计的,其目标是实现和Paxos算法相同的功能,但更加容易理解和实现。Raft算法在分布式系统中尤其关键,因为它帮助系统中的多个节点就其数据的准确状态达成一致。Raft算法主要通过以下几个关键......
  • 如何把音乐的伴奏提取出来?这个方法轻松实现
    在音乐的浩瀚宇宙中,每一首歌曲都是独一无二的创作。而在这份创作中,伴奏往往扮演着举足轻重的角色。它如同音乐的骨架,支撑着整首歌曲的旋律与情感。然而,想要从完整的音乐作品中单独提取出伴奏部分,对于许多音乐爱好者来说,却是一个不小的挑战。幸运的是,现在有一种方法,能够轻松实现......
  • AI实战 | 由浅入深,手把手带你实现Java转型学习助手
    扣子(coze.cn)是一款用来开发新一代AIChatBot的应用编辑平台,无论你是否有编程基础,都可以通过这个平台来快速创建各种类型的ChatBot,并将其发布到各类社交平台和通讯软件上!2月1日,扣子国内版已经正式上线啦~赶快来体验一下吧!一转眼,ChatGPT已经在AI界炙手可热超过一年,堪......
  • flutter 专题十二 Flutter Fair逻辑动态化架构设计与实现
    数据逻辑处理布局中的逻辑处理Flutter类型数据处理一、数据逻辑处理我们接触的每一个Flutter界面,大多由布局和逻辑相关的代码组成。如Flutter初始工程的CountingDemo的代码:class_MyHomePageStateextendsState<MyHomePage>{//变量int_counter=0;//......
  • Java中定时任务实现方式及源码剖析
    概述在企业级应用开发场景中,定时任务占据着至关重要的地位。比如以下这些场景:用户4个小时以内没有进行任何操作,就自动清除用户会话。每天晚上凌晨自动拉取另一个业务系统的某部分数据。每隔15分钟,自动执行一段逻辑,更新某部分数据。类似的场景会频繁出现在我们的日常开发中......
  • 使用Rust语言实现基本图像识别
    Rust是一种注重安全性和并发性的编程语言,适合进行高效的系统级开发。以下是使用Rust语言实现Sobel边缘检测的代码示例。代码实现为了实现图像处理,我们将使用image和ndarray库来处理图像数据。toml[dependencies]image="0.24.3"ndarray="0.15.4"Rust代码rustexterncr......
  • C++-第26课-哈希表:从概念到实现的深入剖析
    目录......
  • 使用Forth实现基本图像识别
    Forth是一种高效、简洁的编程语言,尽管主要用于嵌入式系统,但它也可以实现一些基础的图像处理任务。以下展示了如何使用Forth实现Sobel算子边缘检测。代码实现以下代码假设使用了一种支持图像处理的Forth环境,或者基于自定义的扩展实现。forth更多内容访问ttocr.com或联系143642......