MySQL 中的 MVCC

1. MySQL 中的 MVCC 是什么?

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

一句话概括:

MVCC 是一种为了提高数据库并发性能 的"魔法"。它通过在某个时间点为每个查询提供一个数据快照 ,使得读操作不会阻塞写操作,写操作也不会阻塞读操作

核心思想:

不像传统的锁机制那样,大家必须排队等别人用完才能访问数据,MVCC 创建了数据的多个版本。当你来读数据时,数据库给你看的是符合你查询时刻条件的一个"历史版本",而其他事务可以同时去修改最新的数据版本,互不干扰。

在 MySQL 的 InnoDB 存储引擎中,MVCC 是通过在每行记录后面保存多个版本来实现的。


2. Read View 在 MVCC 中如何工作?

Read View 可以理解为一个 "数据可见性快照""判断规则" 。当事务发起一个一致性读 (比如普通的 SELECT ...)时,InnoDB 会为这个事务生成一个 Read View,用它来决定当前事务能看到哪个版本的数据。

Read View 的核心组成部分:

  1. m_ids : 生成 Read View 时,系统中活跃(尚未提交)的所有事务ID的列表。
  2. min_trx_id : m_ids 中最小的事务ID。
  3. max_trx_id : 生成 Read View 时,系统应该分配给下一个事务的ID。
  4. creator_trx_id: 创建这个 Read View 的事务自己的ID。

判断规则(工作流程):

每行数据都有两个隐藏字段:

  • trx_id: 最近一次修改这行数据的事务ID。
  • roll_pointer: 指向该行数据上一个版本的指针(存储在 undo log 中),形成一个版本链。

当一行数据被访问时,InnoDB 会顺着版本链,根据 Read View 的规则,从最新版本开始逐个判断

  1. 如果 trx_id < min_trx_id

    • 说明修改这行数据的事务在本次 Read View 创建之前就已经提交了。
    • 结论:这个版本对当前事务可见。
  2. 如果 trx_id >= max_trx_id

    • 说明修改这行数据的事务在本次 Read View 创建之后才开启的。
    • 结论:这个版本对当前事务不可见。 需要顺着 roll_pointer 去找更旧的版本。
  3. 如果 min_trx_id <= trx_id < max_trx_id

    • 说明修改这行数据的事务在创建 Read View 时可能活跃,也可能已提交。需要进一步判断:
    • 如果 trx_idm_ids 列表中 ,说明该事务当时还活跃着(未提交)结论:这个版本对当前事务不可见。
    • 如果 trx_id 不在 m_ids 列表中 ,说明该事务在创建 Read View已经提交 了。结论:这个版本对当前事务可见。
  4. 如果 trx_id == creator_trx_id

    • 说明这行数据是当前事务自己修改的。
    • 结论:这个版本对当前事务可见。

简单总结: Read View 就像一个安检员,它只允许你看到那些在你"到场"(事务开始)之前就已经"坐稳"(事务提交)的数据,而不会让你看到那些后来才"进场"(事务开始)或还在"走动"(事务未提交)的数据。


3. 如果没有 MVCC 会怎样?

如果没有 MVCC,MySQL 要实现并发控制,将完全依赖于锁机制。这会带来一系列严重的问题:

  1. 严重的读写阻塞

    • 读会阻塞写 :当一个事务在执行一个长时间的查询时(例如 SELECT COUNT(*) FROM huge_table),它需要获取读锁。在这期间,任何其他事务都无法修改这张表里的任何数据,只能等待。
    • 写会阻塞读:当一个事务在修改数据时,它会获取写锁。在这期间,其他所有事务都无法读取这些被锁住的数据。
  2. 并发性能急剧下降

    • 在高并发场景下(如电商秒杀、热门文章评论),大量的读写请求会相互阻塞,形成长长的等待队列。数据库的吞吐量(单位时间内处理的请求数)会变得非常低,响应时间变长,用户体验极差。
  3. 死锁几率增加

    • 复杂的锁机制(如行锁、间隙锁等)在交织等待时更容易产生死锁。数据库需要花费额外的资源来检测和解除死锁,这本身也是一种性能损耗。

总结对比表:

特性 有 MVCC 的世界 没有 MVCC 的世界
读写并发 。读写互不阻塞,可以同时进行。 。读写相互阻塞,需要排队。
性能 。尤其适合读多写少的应用。 。高并发下性能瓶颈明显。
实现方式 通过数据多版本和 Read View 实现。 完全依赖于各种锁(共享锁、排他锁)。
用户体验 流畅,响应快。 卡顿,经常遇到"等待超时"。

最终总结

  • MVCC 是 InnoDB 实现高并发的核心技术,它通过维护数据的多个版本来让读写操作不再相互等待。
  • Read View 是 MVCC 的"裁判",它定义了一套清晰的规则,来决定在某个特定时刻,一个事务能看到哪些数据版本。
  • 没有 MVCC,读写冲突加剧、性能骤降、死锁频发。
相关推荐
旺仔学长 哈哈16 分钟前
Spring Boot 智能停车场管理系统---附源码+数据库文档
数据库·spring boot·后端·智能停车场
ClickHouseDB33 分钟前
ClickHouse托管Postgres:OLTP+OLAP,新能力解锁最佳数据平台
java·前端·数据库
数智化管理手记1 小时前
主数据重复、错漏频发?一站式主数据管理平台如何落地?
大数据·运维·数据库·人工智能·数据挖掘
吴声子夜歌1 小时前
MongoDB 4.2——选择片键
数据库·mongodb
天天进步一点点2 小时前
QSqlQuery删除sqlite数据库执行drop数据表报错database table is locked unable to fetch row问题
数据库·oracle·sqlite
音视频工程实战2 小时前
PromptQL 新手入门与实战指南
数据库·sql·算法
清川渡水2 小时前
NL2SQL 的正确打开方式:从「AI 猜 SQL」到「置信度闭环」的工程化落地
数据库·人工智能·sql
TDengine (老段)2 小时前
TDengine Go 与 Rust 连接器 — 高性能异步访问
大数据·数据库·物联网·golang·rust·时序数据库·tdengine
东方佑3 小时前
MA-RMSNorm:打破“缩放换智能”的魔咒,大模型归一化的一次范式革命!
数据库·人工智能·计算机视觉
云和恩墨3 小时前
「云帆计划·长沙站」活动成功举办,云和恩墨与紫薇垣和湖南金悦科技分别签约并授牌,本地伙伴生态建设加速
数据库·科技