MVCC是如何实现的

多版本并发控制(MVCC,Multi-Version Concurrency Control)是一种用于实现数据库并发控制的技术,允许多个事务同时读取和写入数据库而不会相互阻塞,从而提高系统的并发性能和响应速度。MVCC通过维护数据的多个版本来实现这一点。以下是MVCC的实现细节,特别是以MySQL的InnoDB存储引擎为例:

关键概念

  1. 版本链(Version Chain)

    • 每个数据行都有多个版本,这些版本通过链表连接起来。每次数据更新时,都会创建一个新版本,而旧版本仍然保留以供并发事务访问。
  2. 隐藏列

    • InnoDB在每行记录中维护两个额外的隐藏列:
      • 事务ID(trx_id):记录创建该版本的事务ID。
      • 回滚指针(roll_ptr):指向撤销日志(undo log),用于恢复旧版本。
  3. 撤销日志(Undo Log)

    • 撤销日志记录了每次数据修改之前的旧值。在事务回滚时,可以利用这些日志恢复数据的旧版本。

MVCC的实现细节

  1. 读取操作

    • 快照读(Snapshot Read) :读取操作会读取事务开始时的快照视图,这个视图包含了在该事务开始时已经提交的数据版本。这样即使其他事务在此期间对数据进行了修改,也不会影响当前事务的读取。
      • 实现快照读的方法是,事务在开始时会记录当前的系统版本号,然后在读取数据时,通过比较每个数据行的事务ID和系统版本号来确定应该读取的数据版本。
    • 当前读(Current Read) :读取操作直接读取最新版本的数据,用于加锁的读取操作,如SELECT ... FOR UPDATESELECT ... LOCK IN SHARE MODE
  2. 写入操作

    • 当事务进行写操作(INSERT、UPDATE、DELETE)时,会创建一个新的数据版本,并将其事务ID记录在新版本的trx_id中。
    • 旧版本的数据不会立即删除,而是保存在撤销日志中,以便并发事务可以继续访问它们。
    • INSERT:插入一条新记录,分配一个新的事务ID,并将其记录在trx_id中。
    • UPDATE:将旧版本标记为删除,并创建一个新版本,新的事务ID记录在新版本的trx_id中。
    • DELETE:将记录标记为删除,并记录删除操作的事务ID。
  3. 事务隔离级别

    • 读已提交(READ COMMITTED):每次读取操作都读取最新的已提交版本。
    • 可重复读(REPEATABLE READ):事务在开始时创建一个一致性视图,所有读取操作都基于这个视图,即使在事务期间有其他事务提交了修改,这个视图仍然保持不变。

MVCC的具体操作流程(以InnoDB为例)

  1. 事务开始

    • 记录当前系统版本号(事务ID)。
  2. 读取操作

    • 检查每行数据的事务ID。
    • 对于快照读,如果数据行的事务ID小于等于当前事务的系统版本号,并且行的删除版本号大于当前事务的系统版本号,则该行数据对当前事务可见。
    • 对于当前读,直接读取最新版本的数据。
  3. 写入操作

    • 为每个写操作分配一个新的事务ID。
    • 将旧版本的数据保存在撤销日志中,以便其他并发事务可以继续访问这些旧版本。
    • 创建新的数据版本,记录新的事务ID。
  4. 事务提交

    • 提交事务,将当前事务ID记录为已提交版本。
    • 释放锁并使新数据版本可见给其他事务。
  5. 事务回滚

    • 使用撤销日志恢复旧版本的数据。

通过上述机制,MVCC在保证数据一致性的同时,提高了并发性能,减少了读写操作的锁竞争,使得数据库系统能够更高效地处理并发事务。

相关推荐
basketball6164 分钟前
Golang:基础语法总结
开发语言·后端·golang
.Cnn7 分钟前
MySQL事务和Spring事务
数据库·后端·mysql·spring
会编程的土豆19 分钟前
Go 里的 init() 到底是什么(彻底理解)
开发语言·后端·golang
PAK向日葵19 分钟前
【C++】深入浅出,理解 C++ 奇异递归模板模式(CRTP)
c++·后端·面试
lzp07911 小时前
元数据驱动开发 - 面向对象编程思想的补充(上)
spring boot·后端·ui
明月_清风9 小时前
加密解密系统完全指南:原理剖析与 Go 实践
后端
小江的记录本10 小时前
【JVM虚拟机】垃圾回收GC:垃圾收集器:CMS:核心原理、回收流程、优缺点、废弃原因(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·spring·面试·maven
冬奇Lab11 小时前
每日一个开源项目(第105篇):Twenty - 跳出 Salesforce 的圈套,定义现代开源 CRM
前端·后端·开源
ServBay12 小时前
月之暗面 Kimi Code 0.4.0 发布,终端 AI 编码助手全面采用 TypeScript,实现毫秒级启动
后端·aigc·ai编程
小江的记录本12 小时前
【JVM虚拟机】垃圾回收GC:垃圾回收算法:标记-清除、标记-复制、标记-整理、分代收集(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·安全·面试