【MySQL】MySQL中的MVCC是什么?它与隔离级别有什么关系?

1、MVCC是什么?

MVCC的核心思想:读不加锁,读写不冲突,通过数据的多个版本实现并发控制

它的实现依赖三个东西:

1、隐藏字段

每行数据有DB_TRX_ID (最近修改该行的事务ID ),DB_ROLL_PTR(回滚指针)

2.Undo Log 版本链

记录数据的历史版本,构成版本链

3.Read View

事务快照,决定当前事务能看到哪些版本

2、MVCC如何工作?

1.版本链

每次更新一行数据时,InnoDB会:

1.把旧版本写入Undo Log

2.新版本指向旧版本(通过回滚指针 )

3.形成一条版本链

bash 复制代码
当前版本→上个版本→更早版本

2.Read View

事务开始读取时,生成一个Read View,包含:

  • m_ids: 当前活跃事务ID 集合
  • min_trx_id:活跃事务中的最小ID
  • max_trx_id:下一个即将分配的事务ID
  • **creator_trx_id:**当前事务自己的ID

然后沿着版本链,按规则判断哪个版本对应当前事务可见。

3.核心关系:不同隔离级别,Read View 生成时机不同

这是理解 MVCC与事务隔离级别关系最关键的一部分

RU 读未提交

基本不用MVCC ,直接读最新版本

  • 不生成Read View
  • 直接读取当前最新数据,不管是否已提交
  • 所以会出现脏读

RC 读已提交

每次SELECT 都生成一个新的Read View

这意味着:

  • 每次查询都能看到别的事务最新提交的数据
  • 所以同一个事务里两次查询,结果可能不同 ,造成不可重复读

RR 可重复读

只在第一次SELECT时 生成Read View ,之后复用同一个

这意味着:

  • 整个事务期间,看到的都是同一个快照
  • 别的事务提交了更新,也看不到,这样就避免了不可重复读

Serializable 串行化

MVCC 退化为基于锁的并发控制

  • 所有SELECT 自动加 lock in share mode
  • 读写相互阻塞
  • MVCC的快照基本不再使用

4、MVCC能解决什么,不能解决什么

可以解决:

  • 脏读:通过 版本链+Read View 只读 已提交的版本
  • 不可重复读:RR 级别复用 Read View,保持快照一致
  • 普通的并发性能:读不加锁,读写不阻塞

不能完全解决的:

  • 幻读: MVCC的快照只能保证读到的行不变 ,但不能阻止别的事务插入新的行

5、那幻读怎么办? MVCC+锁 一起上!

RR 隔离级别下,InnoDB用 MVCC+Next-Key Lock 组合拳来对付幻读

场景:

普通SELECT 快照读

MVCC,读历史快照,看不到新插入的行

SELECT ... FOR UPDATE 当前读

Next-Key Lock,锁住间隙,阻止插入

UPDATE/DELETE 当前读

Next-Key Lock 同样锁间隙

所以:

MVCC 负责快照读的一致性 ,Next-Key Lock 负责当前读时防止幻读

6、总结

MVCC是InnoDB实现事务隔离的底层机制

不同隔离级别的本质区别在于Read View的生成时机不同
RC读已提交 每次查询都生成新的Read View
RR可重复读 只生成一次并复用

MVCC负责快照读的一致性 ,配合Next-Key Lock 解决当前读的幻读问题

相关推荐
NineData1 小时前
还在轮询 MySQL 吗?用 NineData 把业务变更直接送进 Kafka
数据库·mysql·kafka·ninedata·数据复制·玖章算术·数据迁移工具
重生之小比特2 小时前
【MySQL 数据库】索引特性
数据库·mysql
Andya_net2 小时前
MySQL | DBeaver Mac版下载、安装与使用指南
数据库·mysql·macos
罗超驿15 小时前
8.数据库约束学习笔记:从非空、默认、唯一与主键约束到主键自增
数据库·mysql
Irene199118 小时前
SQL示例:分别使用 MySQL 和 Oracle 创建表,MySQL 插入数据建索引(自增主键、指定主键的区别,VARCHAR,VARCHAR2)
mysql·oracle
用户42176328140718 小时前
如何用java实现一个简单的并发版本控制MVCC
mysql
阿维的博客日记18 小时前
求解深分页问题,last pk适合什么情况
java·mysql·深分页
__water19 小时前
【下载配置Mysql】
mysql
Dxy123931021621 小时前
MySQL 连表查询更新:从理论到实践
数据库·mysql