【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 解决当前读的幻读问题

相关推荐
lisw054 小时前
MySQL 数据库:概念、历史、内容与展望!
数据库·mysql
南城以南溫暖如初1474 小时前
社群电商实战指南:从零搭建高转化社区的技术架构
java·spring boot·mysql·系统架构·vue·mybatis
南城以南溫暖如初1474 小时前
会员返利商城系统开发实战:架构设计与实现指南
java·spring boot·mysql·vue·mybatis
虎虎(_ _)。゜zzZ5 小时前
FastAPI-lifespan生命周期管理实战
mysql·aigc·fastapi·大模型部署·lifespan·python异步
数据库小学妹6 小时前
MySQL死锁排查:锁机制原理、死锁日志与information_schema定位
运维·数据库·mysql
Sirens.6 小时前
MySQL数据库:视图
数据库·mysql
山岚的运维笔记6 小时前
mysql 专业笔记 -- 第 1 章:MySQL 入门
运维·数据库·笔记·后端·学习·mysql·dba
吃饱了得干活7 小时前
MySQL 内核剖析:ACID 实现、引擎对决、B+树、索引与主从复制闭环
后端·mysql
梦想不只是梦与想7 小时前
MySQL 中的窗口函数
数据库·mysql·窗口函数
拾光Ծ10 小时前
【MySQL】对表数据的操作:增删查改(CRUD)
android·数据库·sql·mysql