首页 > 其他分享 >InnoDB存储引擎对MVCC的实现

InnoDB存储引擎对MVCC的实现

时间:2024-03-05 22:15:53浏览次数:16  
标签:存储 读取 事务 InnoDB 版本 MVCC 数据 ID

一 多版本并发控制 (Multi-Version Concurrency Control)

1、读操作(SELECT):

当一个事务执行读操作时,它会使用快照读取。快照读取是基于事务开始时数据库中的状态创建的,因此事务不会读取其他事务尚未提交的修改。具体工作情况如下:

  • 对于读取操作,事务会查找符合条件的数据行,并选择符合其事务开始时间的数据版本进行读取。
  • 如果某个数据行有多个版本,事务会选择不晚于其开始时间的最新版本,确保事务只读取在它开始之前已经存在的数据。
  • 事务读取的是快照数据,因此其他并发事务对数据行的修改不会影响当前事务的读取操作。

2、写操作(INSERT、UPDATE、DELETE):

当一个事务执行写操作时,它会生成一个新的数据版本,并将修改后的数据写入数据库。具体工作情况如下:

  • 对于写操作,事务会为要修改的数据行创建一个新的版本,并将修改后的数据写入新版本。
  • 新版本的数据会带有当前事务的版本号,以便其他事务能够正确读取相应版本的数据。
  • 原始版本的数据仍然存在,供其他事务使用快照读取,这保证了其他事务不受当前事务的写操作影响。

3、事务提交和回滚:

  • 当一个事务提交时,它所做的修改将成为数据库的最新版本,并且对其他事务可见。
  • 当一个事务回滚时,它所做的修改将被撤销,对其他事务不可见。

4、版本的回收:

为了防止数据库中的版本无限增长,MVCC 会定期进行版本的回收。回收机制会删除已经不再需要的旧版本数据,从而释放空间。

MVCC 通过创建数据的多个版本和使用快照读取来实现并发控制。读操作使用旧版本数据的快照,写操作创建新版本,并确保原始版本仍然可用。这样,不同的事务可以在一定程度上并发执行,而不会相互干扰,从而提高了数据库的并发性能和数据一致性。

 

 

InnoDB 对 MVCC 的实现

MVCC 的实现依赖于:隐藏字段、Read View、undo log。在内部实现中,InnoDB 通过数据行的 DB_TRX_IDRead View 来判断数据的可见性,如不可见,则通过数据行的 DB_ROLL_PTR 找到 undo log 中的历史版本。每个事务读到的数据版本可能是不一样的,在同一个事务中,用户只能看到该事务创建 Read View 之前已经提交的修改和该事务本身做的修改

 

隐藏字段

在内部,InnoDB 存储引擎为每行数据添加了三个 隐藏字段

  • DB_TRX_ID(6字节):表示最后一次插入或更新该行的事务 id。此外,delete 操作在内部被视为更新,只不过会在记录头 Record header 中的 deleted_flag 字段将其标记为已删除
  • DB_ROLL_PTR(7字节) 回滚指针,指向该行的 undo log 。如果该行未被更新,则为空
  • DB_ROW_ID(6字节):如果没有设置主键且该表没有唯一非空索引时,InnoDB 会使用该 id 来生成聚簇索引

 

 

Read View 

主要是用来做可见性判断,里面保存了 “当前对本事务不可见的其他活跃事务”

主要有以下字段:

  • m_low_limit_id:目前出现过的最大的事务 ID+1,即下一个将被分配的事务 ID。大于等于这个 ID 的数据版本均不可见
  • m_up_limit_id:活跃事务列表 m_ids 中最小的事务 ID,如果 m_ids 为空,则 m_up_limit_idm_low_limit_id。小于这个 ID 的数据版本均可见
  • m_idsRead View 创建时其他未提交的活跃事务 ID 列表。创建 Read View时,将当前未提交事务 ID 记录下来,后续即使它们修改了记录行的值,对于当前事务也是不可见的。m_ids 不包括当前事务自己和已提交的事务(正在内存中)
  • m_creator_trx_id:创建该 Read View 的事务 ID

 

undo-log

undo log 主要有两个作用:

  • 当事务回滚时用于将数据恢复到修改前的样子
  • 另一个作用是 MVCC ,当读取记录时,若该记录被其他事务占用或当前版本对该事务不可见,则可以通过 undo log 读取之前的版本数据,以此实现非锁定读

 

 

 

MVCC➕Next-key-Lock 防止幻读

InnoDB存储引擎在 RR 级别下通过 MVCCNext-key Lock 来解决幻读问题:

1、执行普通 select,此时会以 MVCC 快照读的方式读取数据

在快照读的情况下,RR 隔离级别只会在事务开启后的第一次查询生成 Read View ,并使用至事务提交。所以在生成 Read View 之后其它事务所做的更新、插入记录版本对当前事务并不可见,实现了可重复读和防止快照读下的 “幻读”

2、执行 select...for update/lock in share mode、insert、update、delete 等当前读

在当前读下,读取的都是最新的数据,如果其它事务有插入新的记录,并且刚好在当前事务查询范围内,就会产生幻读!InnoDB 使用 Next-key Lock 来防止这种情况。当执行当前读时,会锁定读取到的记录的同时,锁定它们的间隙,防止其它事务在查询范围内插入数据。只要我不让你插入,就不会发生幻读

标签:存储,读取,事务,InnoDB,版本,MVCC,数据,ID
From: https://www.cnblogs.com/balfish/p/18055093

相关文章

  • mysql报错:SQL 错误 [1030] [HY000]: Got error 100 - 'InnoDB error' from storage en
    在mysql中进行alter时,报错:SQL错误[1030][HY000]:Goterror100-'InnoDBerror'fromstorageengine 原因:在配置my.cnf或my.ini里面innodb_force_recovery参数的值大于0,它默认值为0,如果大于0,innodb就会禁用insert、update、delete、alter语句。解决方式:在配置my.cn......
  • K8S --存储卷
    存储卷容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。首先,当容器崩溃时,kubelet会重启它,但是容器中的文件将丢失——容器以干净的状态(镜像最初的状态)重新启动。其次,在Pod中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes中......
  • 存储过程Stored Procedure
    1、前言 存储过程(StoredProcedure),是一组为了完成特定功能的SQL语句,集经编译后存储在数据库中,用户通过指定存储过程的名字并给出参数,如果该存储过程带有参数来执行。简单的说就是专门干一件事一段sql语句。可以由数据库自己去调用,也可以由程序去调用。 存储过程的优点:......
  • mysql8.0 性能优化配置 innodb_buffer_pool_size(配置原则和方式)
    1. BufferPool缓冲池是主内存中的一个区域,InnoDB在访问表和索引数据时会在该区域进行缓存。缓冲池允许直接从内存访问频繁使用的数据,这加快了处理速度。在专用服务器上,通常会将高达80%的物理内存分配给缓冲池。2.简单优化把innodb_buffer_pool_size设置为1G。专用服务......
  • 从MySQL到ByteHouse,抖音精准推荐存储架构重构解读
    更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群抖音依靠自身推荐系统为用户推送可能感兴趣的视频内容,其中兴趣圈层是推荐的重要能力,通过理解核心用户的偏好特征,判断两者偏好的相似性,从而构建同类用户的兴趣圈层,实现精准推荐。以往的兴趣圈......
  • Git无法正常工作,因为检测到XXX存储库可能不安全(unsafe repository)的解决方法
    背景前两天因为对硬盘进行了误操作,导致系统无法进入,只能重新安装。待系统安装完毕后第一时间将VS下了回来。在VS开发环境部署完毕后,我打开了自己的解决方案,结果在“Git更改”选项卡内遇到了如下图的提示(分别是VS2022和VS2019): 过程在点击“将其标记为安全”后该存储库可以正......
  • MySQL之视图、触发器、存储过程、函数和流程控制
    视图什么是视图视图就是通过查询得到一张虚拟表,然后保存下来,下次可以直接使用其实视图也是表为什么要用视图如果要频繁的操作一张虚拟表(拼表组成的),你就可以制作成视图,后续直接操作如何操作#固定语法createview表名as虚拟表的查询SQL语句#具体操作create......
  • MySQL之存储引擎
    什么是存储引擎数据库存储引擎是数据库底层软件组织,数据库管理系统使用数据引擎进行创建、查询、更新和删除数据。日常生活中文件格式有很多种,并且针对不同的文件格式会有对应不同存储方式和处理机制(txt、pdf、word、mp4等等)不同的存储引擎提供不同的存储机制、索引机制......
  • 在K8S中,如果后端nfs存储的ip发生变化如何解决?
    在Kubernetes(K8S)中,如果后端NFS(NetworkFileSystem)存储的IP地址发生了变化,你需要更新与之相关的PersistentVolume(PV)或PersistentVolumeClaim(PVC)以及StorageClass中关于NFS服务器IP的配置信息,确保K8S集群内的Pod能够正确连接到新的NFS存储位置......
  • 数据结构之线性表(顺序存储表)
    php<?php/***CreatedbyPhpStorm.*User:SillyCat*Date:2024/3/2*Time:18:47*/classSequenceList{private$item=array();private$length=0;publicfunction__construct(){//$this->item=$item;......