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

mvcc 简介

MVCC(Multi-Version Concurrency Control,多版本并发控制)是数据库中用于解决并发访问冲突的核心机制,广泛应用于InnoDB、PostgreSQL等主流数据库。其核心思想是为数据维护多个版本,使得读写操作可以并发执行而不互相阻塞,从而在保证事务隔离性的同时提升并发性能。

为什么需要MVCC?

传统的并发控制依赖锁机制(如行锁、表锁),但锁会导致读写冲突(例如:读操作需要等待写操作释放锁,或写操作等待读操作释放锁),在高并发场景下严重影响性能。

MVCC通过让读操作访问数据的历史版本,避免了对当前写入版本的依赖,从而实现“读不加锁、写不阻塞读”,极大提升了并发效率。

MVCC的核心原理

MVCC的实现依赖三个关键组件:隐藏列undo日志Read View(读视图)

1. 隐藏列:数据版本的“身份标识”

数据库表中的每行数据,除了用户定义的列外,还会隐含几个系统列(以InnoDB为例):

  • DB_TRX_ID:记录最后一次修改该数据行的事务ID(6字节)。
  • DB_ROLL_PTR:回滚指针(7字节),指向该数据行的上一个版本(存储在undo日志中)。
  • DB_ROW_ID:行唯一标识(6字节),当表没有主键时,InnoDB会用它生成聚簇索引。

这些隐藏列是MVCC追踪数据版本的基础。

2. undo日志:数据版本的“历史档案”

当事务修改数据时,数据库会先将数据的旧版本写入undo日志(回滚日志),然后再更新当前数据行。

  • 例如:事务T1修改了一行数据,旧版本会被存入undo日志,当前数据行的DB_ROLL_PTR指向这个旧版本;若事务T2再次修改该行,新的旧版本(T1修改后的版本)会被存入undo日志,DB_ROLL_PTR更新为指向T2的旧版本,形成一条版本链(通过回滚指针串联的历史版本)。
  • undo日志的另一个作用是事务回滚:若事务执行失败,可通过undo日志恢复数据到修改前的状态。
3. Read View:判断版本可见性的“规则”

Read View(读视图)是事务在读取数据时生成的一个“快照”,用于判断当前事务能看到哪个版本的数据。它包含四个核心参数:

  • m_ids:当前活跃事务的ID集合(即尚未提交的事务)。
  • min_trx_id:m_ids中最小的事务ID(当前活跃事务的最小ID)。
  • max_trx_id:数据库下一个将要分配的事务ID(大于当前所有活跃事务ID)。
  • creator_trx_id:生成该Read View的事务自身的ID。
4. 可见性判断规则

当事务读取数据时,会通过Read View判断数据版本链中哪个版本对自己可见,规则如下(假设数据版本的DB_TRX_IDtrx_id):

  1. trx_id == creator_trx_id:该版本是当前事务自己修改的,可见。
  2. trx_id < min_trx_id:修改该版本的事务已提交(因为其ID小于所有活跃事务ID),可见。
  3. trx_id >= max_trx_id:修改该版本的事务是在当前事务之后启动的,不可见。
  4. min_trx_id <= trx_id < max_trx_id
    • trx_idm_ids中(该事务仍活跃):不可见。
    • trx_id不在m_ids中(该事务已提交):可见。

如果当前版本不可见,事务会通过DB_ROLL_PTR回溯到上一个版本,重复判断,直到找到可见版本或版本链结束(此时返回空)。

MVCC与事务隔离级别的关系

MVCC的行为会根据事务隔离级别调整,核心差异在于Read View的生成时机

  • Read Committed(读已提交):每次执行查询时都会生成新的Read View。因此,同一事务中两次查询可能看到不同的结果(因为中间可能有其他事务提交)。
  • Repeatable Read(可重复读,InnoDB默认):仅在事务第一次执行查询时生成Read View,后续查询复用该视图。因此,同一事务中多次查询看到的结果一致(避免了不可重复读)。

(注:Serializable隔离级别通常不依赖MVCC,而是通过加锁实现;Read Uncommitted直接读取最新版本,不适用MVCC。)

MVCC的优势

  1. 读写不冲突:读操作无需加锁,直接访问历史版本;写操作仅锁定当前版本,不阻塞读,极大提升并发性能。
  2. 简化隔离级别实现:通过Read View的生成时机和可见性规则,自然实现了Read Committed和Repeatable Read隔离级别的语义。
  3. 避免锁竞争:减少了传统锁机制的阻塞和等待,降低了死锁风险。

总结

MVCC通过隐藏列记录版本标识undo日志维护历史版本链Read View判断可见性,实现了“多版本并发访问”。其核心价值是在保证事务隔离性的前提下,最大化读写并发效率,是现代数据库高性能的关键机制之一。

http://www.dtcms.com/a/605107.html

相关文章:

  • UniApp 商品分类左右联动技术文档
  • pytest 入门指南:Python 测试框架从零到一(2025 实战版)
  • SpringBoot教程(三十三)| SpringBoot集成MinIO
  • 【开题答辩全过程】以 基于.NET MVC的线上鞋服交易系统设计与实现为例,包含答辩的问题和答案
  • MySQL 全体系深度解析(存储引擎、事务、日志、MVCC、锁、索引、执行计划、复制、调优)
  • SpringMVC基础教程(1)--MVC/DispathcerServlet
  • 在streampark运行paimon-flink-action-1.20.0.jar
  • AI得贤面试智能体:重构企业招聘新范式
  • 硅基计划6.0 陆 JavaEE HttpHttps协议
  • 稳定边界层高度参数化方案的回归建模
  • 企业网站推广方法wap网站预览
  • 可以做推广的门户网站wordpress适合中国的小插件介绍
  • Dubbo服务治理全解析:从零搭建高可用微服务架构
  • java List怎么转换为Vector
  • 2023年辽宁省数学建模竞赛-B题 数据驱动的水下导航适配区分类预测-基于支持向量机对水下导航适配区分类的研究
  • 机器学习--KNN算法中的距离、范数、正则化
  • openGauss向量数据库功能实操测评:轻量部署下的高维检索能力
  • php做网站还是linuxseo服务外包费用
  • 《算法通关指南:算法基础篇 ---- 二维前缀和 — 1. 【模板】二维度前缀和,2.激光炸弹》
  • SpringBoot+openGauss DataVec构建高效RAG知识库实践
  • JVM 垃圾回收算法的详细介绍
  • 生成式引擎优化(GEO)实用指南(三):结构化内容与AI优化策略
  • 114啦怎么建设网站怎么样推广自己的公司
  • 可视化图标开发“懂一点”|数据可视化术语表
  • SpringMVC(1)学习
  • 高频Linux 面试题
  • 芜湖效能建设网站重庆发布公众号
  • Spring Boot 多环境配置详解:Maven Profile vs 启动参数注入
  • 《Chart.js 饼图:高效与灵活的数据可视化工具详解》
  • 力扣每日刷题251113