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,读写冲突加剧、性能骤降、死锁频发。
相关推荐
毕设十刻2 小时前
基于Vue的鲜花销售系统33n62(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
Boilermaker19922 小时前
【MySQL】数据目录与日志开篇
数据库·mysql
李慕婉学姐2 小时前
Springboot加盟平台推荐可视化系统ktdx2ldg(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
小满、5 小时前
MySQL :实用函数、约束、多表查询与事务隔离
数据库·mysql·事务·数据库函数·多表查询
百***35336 小时前
PostgreSQL_安装部署
数据库·postgresql
rayylee8 小时前
生活抱怨与解决方案app
数据库·生活
Lucifer三思而后行9 小时前
使用 BR 备份 TiDB 到 AWS S3 存储
数据库·tidb·aws
百***170710 小时前
Oracle分页sql
数据库·sql·oracle
qq_4369621810 小时前
数据中台:打破企业数据孤岛,实现全域资产化的关键一步
数据库·人工智能·信息可视化·数据挖掘·数据分析