MVCC 与乐观锁,RR的本质

MySQL InnoDB 引擎最核心的底层原理!

1. MVCC 与乐观锁的"灵魂契合"

MVCC 本质上就是一种乐观并发控制的实现手段。

  • 传统悲观锁:我想改数据,先加锁,别人别动。
  • MVCC(乐观) :我想改数据,我不加锁,我先基于当前的"快照"去读。等我真要更新时,我再检查这期间有没有别人改过它。
    • 读取时:完全不加锁,通过读取"历史版本链"来实现非阻塞读。
    • 更新时:InnoDB 会检查当前行的最新版本是否和你读取时的版本一致(类似乐观锁的版本号校验)。如果不一致,说明有冲突,更新可能会失败或需要重新尝试。

2. 可重复读(RR)是如何通过 MVCC 实现的?

这是面试和实战中的高频考点。

  • 读视图(Read View) :当你开启一个事务并执行第一次 SELECT 时,InnoDB 会生成一个"快照"(Read View)。
  • 版本链 :每一行数据都有一个隐藏的版本号。修改数据时,旧数据不会直接覆盖,而是被移到"undo log"中形成一条版本链。
  • 隔离原理 :在"可重复读"级别下,整个事务期间都复用第一次生成的 Read View。这意味着,无论别人怎么修改并提交数据,你看到的永远是事务开始时 那个版本的数据。这就是"可重复读"的真相------你不是在读最新的数据,你是在读历史快照。

3. 一个关键的补充:MVCC 并不是"完全不加锁"

虽然 MVCC 让普通的 SELECT 实现了无锁并发,但在写操作 时,它依然依赖悲观锁。

  • 读写不冲突:这是 MVCC 的功劳。你在读 V1 版本,我在写 V2 版本,互不影响。
  • 写写必冲突 :如果两个人都要把 V1 改成 V2,这时候 MVCC 就不够用了。InnoDB 依然会给这一行加上排他锁(X锁) 。
    • 流程:事务 A 要更新 -> 获取排他锁 -> 检查版本链 -> 修改数据生成新版本 -> 提交释放锁。

所以,准确的结论是:MVCC 解决了"读写冲突",但"写写冲突"依然靠排他锁解决。

总结知识体系

你现在可以这样构建知识图谱:

  • MVCC = 乐观读 + 历史版本链 + Read View。
  • 可重复读 = 全程复用同一个 Read View。
  • FOR UPDATE = 放弃 MVCC 的乐观读,强制走悲观锁(排他锁)。
  • 死锁 = 悲观锁使用不当(顺序交叉)导致的。
相关推荐
paopaokaka_luck9 小时前
美食推荐系统(协同过滤算法推荐、AI助手、HanLP中文分词、 ECharts可视化分析、菜谱学习与话题交流)
java·spring boot·mysql·tomcat·echarts
sunburn-10 小时前
数据库操作完整教程:从基础到实战
java·数据库·mysql
bksczm10 小时前
MySQL之读写分离与分库分表
数据库·mysql
梅孔立10 小时前
.mdb Access_MDB历史数据文件迁移MySQL实战教程-可直接投喂给ai参考这个帮你完成迁移
数据库·mysql·adb
时间售卖铺10 小时前
MySQL 数据库账户及授权
运维·数据库·mysql·云原生
2301_322414280418 小时前
基于SpringBoot+Vue的休闲零食超市管理系统的设计与实现59004-计算机毕设 原创(免费领源码+部署教程+开发环境)
java·vue.js·spring boot·redis·mysql·决策树·推荐算法
库库的数据库笔记21 小时前
国产信创数据库的MySQL兼容性深度对比解析
大数据·数据库·mysql·oceanbase·政务
吹什么轩1 天前
MySQL:数据库基础
数据库·mysql
FluxDB1 天前
用 Rust + GPUI 重做数据库客户端
数据库·mysql
Yyyyyy~1 天前
【Mysql】增删查改操作
数据库·mysql