当前位置: 首页 > news >正文

数据库的MVCC机制详解

MVCC(Multi-Version Concurrency Control,多版本并发控制)是数据库系统中常用的并发控制机制,它允许数据库在同一时间点保存数据的多个版本,从而实现非阻塞的读操作,提高并发性能。

MVCC的核心思想是:

  • 读不阻塞写,写不阻塞读
  • 每个事务看到的是数据库在事务开始时的一致性快照
  • 通过版本链实现数据的多版本存储

为什么需要MVCC?

我们知道数据库有行锁,表锁来保证数据的安全性,但同时也有可能导致阻塞(响应缓慢)和死锁(不可用)。而MVCC正是解决这些问题的机制。MVCC通过保存数据的历史版本来避免读写冲突,这样读操作不会阻塞写操作,写操作也不会阻塞读操作。

MVCC主要功能有哪些?

1) 数据版本管理

2) 事务隔离级别控制 

3) 并发冲突检测与解决

4) 数据一致性维护

1) 数据版本管理

数据库为每一行数据会维护一个版本链,其中有两个主要的信息,事务id与回滚指针。

回滚指针指向的是回滚日志

  • 每次修改数据时(如 INSERT/UPDATE/DELETE),数据库会记录旧数据的 undo log。

  • Undo log 按事务隔离,形成版本链:

    • INSERT 操作:记录插入数据的 undo log(用于回滚时删除)。

    • UPDATE/DELETE 操作:记录旧数据的完整拷贝(用于构建历史版本)。

版本链的构建流程

以一行数据为例

  1. 初始状态
    数据行 id=1,值 value=A,事务ID txid=100,回滚指针指向 NULL

    | id=1 | value=A | DB_TRX_ID=100 | DB_ROLL_PTR=NULL |
  2. 事务 txid=200 更新值

    • 生成新版本数据 value=B,更新 DB_TRX_ID=200

    • 将旧版本数据 value=A 写入 undo log。

    • 新版本的回滚指针指向旧版本的 undo log 地址。

    新版本数据:| id=1 | value=B | DB_TRX_ID=200 | DB_ROLL_PTR=0x123(指向 undo log 中的旧版本)|
  3. 事务 txid=300 再次更新值

    • 生成新版本 value=C,更新 DB_TRX_ID=300

    • 旧版本 value=B 写入 undo log。

    • 版本链形成:C ← B ← A(通过回滚指针链接)。

2) 事务隔离级别控制 

可见性规则(判断数据是否可见)

事务读取数据时,需根据 快照版本 和 事务ID 判断哪个版本对其可见。规则如下:

1. Read View(读视图)

每个事务在首次查询时会生成一个 Read View,包含:

  • 活跃事务列表:当前未提交的事务ID集合。

  • 最小活跃事务ID(low_limit_id):活跃事务中的最小ID。

  • 最大事务ID(up_limit_id):下一个即将分配的事务ID(即当前最大ID+1)。

2. 可见性判断逻辑

对数据行的每个版本,检查其 DB_TRX_ID

  1. 如果 DB_TRX_ID < low_limit_id 且不在活跃事务列表中 → 可见(该版本在事务开始时已提交)。

  2. 如果 DB_TRX_ID >= up_limit_id → 不可见该版本在事务开始后创建)。

  3. 如果 DB_TRX_ID 在活跃事务列表中 → 不可见该版本的事务尚未提交)。

  4. 其他情况需进一步判断(如版本是否被删除)。

不同隔离级别实现
1. 读已提交(Read Committed)
  • 每次查询生成新的 Read View。

  • 能看到其他事务 已提交的最新修改

2. 可重复读(Repeatable Read)
  • 事务开始时生成一次 Read View,后续查询沿用该视图。

  • 始终看到事务开始时的数据快照,其他事务的修改不可见(解决不可重复读)。

3. 幻读的特殊处理
  • MySQL 通过 Next-Key Lock(间隙锁+行锁)解决幻读问题。

  • PostgreSQL 依赖快照隔离,但严格的可串行化隔离级别需要显式锁。

3) 并发冲突检测与解决

常见的并发冲突类型
  1. 写-写冲突(Lost Update)
    两个事务同时修改同一数据,后提交的事务覆盖前一个事务的结果(如库存扣减场景)。

  2. 读-写冲突(Dirty Read/Unrepeatable Read)
    事务 A 读取数据后,事务 B 修改了该数据,导致事务 A 的后续操作不一致。

  3. 幻读(Phantom Read)
    事务 A 读取某范围数据时,事务 B 插入或删除了符合该范围的数据,导致事务 A 两次读取结果不一致。

冲突解决策略
  1. 版本链与回滚

    • 当检测到冲突时(如写-写冲突),MVCC通过版本链回溯到可用的旧版本,确保读操作不受影响。
    • 例如,InnoDB的undo log存储旧版本数据,供回滚和一致性读使用
  2. 垃圾回收机制

    • 定期清理无效版本(如PostgreSQL的VACUUM、MySQL的purge线程)。
    • 通过检查xmax状态(已提交或未提交)和事务活跃状态,删除过期版本

相关文章:

  • C# ref out关键字 理解学习记录
  • 国家科技奖项目答辩ppt设计_科技进步奖PPT制作_技术发明奖ppt美化_自然科学奖ppt模板
  • Linux 的准备工作
  • 大小端判断函数
  • 【I/O】文件系统操作
  • 2024年第十五届蓝桥杯CC++大学A组--成绩统计
  • 贪心算法:部分背包问题深度解析
  • openwrt软路由配置-----扩展系统空间
  • 【Linux】39.一个基础的HTTP Web服务器
  • 入侵检测系统(IDS)和入侵防御系统(IPS)有啥区别?
  • Linux系统05---进程
  • 安科瑞测频仪表:新能源调频困局的破局者
  • 【AI提示词】常青笔记生成器
  • 鸿蒙开发中的并发与多线程
  • 程序化广告行业(72/89):Tag Manager系统代码操作与行业发展剖析
  • yarn:error Error: certificate has expiredERR_OSSL_EVP_UNSUPPORTED解决
  • 【QT】QT的消息盒子和对话框(自定义对话框)
  • LLC工作模态详解
  • 数据结构与算法-图论-复习1(单源最短路,全源最短路,最小生成树)
  • 突破,未观测地区罕见极端降雨的估计
  • 专业的app网站开发/百度指数资讯指数
  • 调查队网站建设/拉新app推广平台排名
  • 做it的在哪个网站找工作/销售外包
  • app手机应用开发公司/热门seo推广排名稳定
  • 美工详情页设计一般多少钱/seo排名软件有用吗
  • 做网站的报价方案/lpl赛区战绩