当前位置: 首页 > news >正文

MySQL 中 MVCC 和锁的关系与配合

MySQL 中 MVCC 和锁的关系与配合

MySQL 的 InnoDB 存储引擎通过MVCC(多版本并发控制)锁机制来处理并发事务。这两者并非各自为政,而是紧密协作、分工明确

  • MVCC主要负责读操作(尤其是普通查询),通过提供数据的历史快照,实现“读写不冲突”,从而极大提升并发性能。
  • 锁机制则负责写操作以及需要强一致性的读操作,通过对数据加锁来保证修改安全,防止数据混乱。

MVCC 与锁机制对比

特性维度MVCC (多版本并发控制)锁机制 (Locking)
核心思想保存数据的多个历史版本,让读操作看到“过去”的快照。对数据对象加锁,使并发操作“排队”执行。
主要应用快照读:即普通的SELECT语句,不加锁,效率最高。当前读SELECT ... FOR UPDATESELECT ... LOCK IN SHARE MODEUPDATEDELETEINSERT
解决的问题主要解决读-写冲突,让读不阻塞写,写也不阻塞读。主要解决写-写冲突,确保并发修改的安全性和隔离性。
依赖的组件Undo Log(构建历史版本链)、Read View(判断版本可见性)。记录锁(Record Lock)、间隙锁(Gap Lock)、临键锁(Next-Key Lock)等。

分工配合详解

1. 快照读:MVCC 独挑大梁

当你执行普通查询(如SELECT * FROM user WHERE id = 1)时,MVCC 全权负责
InnoDB 会根据当前事务隔离级别生成一个Read View,然后利用Undo Log中的版本链,快速返回一个符合隔离级别要求的数据快照。整个过程不加任何锁,即使其他事务正在修改同一行,查询也不会被阻塞,实现了“读写并发”。

2. 当前读:锁机制接管控制

当你执行修改语句或加锁查询(如UPDATEDELETESELECT ... FOR UPDATE)时,锁机制开始发挥作用

  • 语句首先执行“当前读”,找到数据的最新版本,并立即为其加上排他锁(X锁)(或根据语句类型加共享锁)。
  • 根据操作类型和隔离级别,还可能添加间隙锁临键锁,防止幻读。
  • 其他事务若想加锁访问该数据,必须等待当前事务释放锁。

3. 同一事务中的协同

在一个较长的事务中,MVCC 和锁机制会根据 SQL 语句动态切换
例如:事务开始时的普通查询(快照读)→ 之后的UPDATE(切换为当前读并加锁)→ 再次普通查询(再次使用 MVCC,但可能受到之前更新的影响)。整个过程由 InnoDB 自动管理,对用户透明。


完整配合流程示例

以下用两个事务(A 和 B)几乎同时操作同一行数据的过程,展示 MVCC 与锁的协作:

  1. 事务 A 启动,执行普通查询
    SELECT * FROM product WHERE id = 1;
    • MVCC 生效,创建Read View,返回数据快照。
    • 未加任何锁,读写互不阻塞。
  2. 事务 B 启动,执行修改
    UPDATE product SET stock = stock - 10 WHERE id = 1;
    • 步骤一(锁定读):先执行“当前读”,找到id=1的最新记录,并加上排他锁(X锁)
    • 步骤二(执行修改):修改数据,并将旧版本写入Undo Log,形成新版本链。
    • 步骤三(持有锁):在事务 B 提交前一直持有排他锁。
  3. 其他事务的“当前读”被阻塞
    若事务 A 或其他事务尝试执行SELECT ... FOR UPDATE或另一个UPDATE操作同一行,锁机制会让它们进入等待状态,直到事务 B 提交释放锁。
  4. 快照读不受影响
    若事务 A 再次执行普通SELECT * FROM product WHERE id = 1;
    • 由于是快照读,它会根据自己一开始生成的Read ViewUndo Log版本链中读取历史版本,不会被排他锁阻塞,立即返回结果。
  5. 事务结束
    事务 B 提交,释放排他锁。其他被阻塞的“当前读”操作获取锁,并看到事务 B 修改后的最新数据。

总结

可以把 MVCC 和锁的关系想象成两个不同的房间:

  • MVCC 像一个高效的阅览室:允许多人同时阅读(快照读),有人做笔记(写操作)时也不影响他人阅读。
  • 锁机制像一个庄重的签约室:一旦有人进去签约(当前读/修改),门就会锁上,其他人必须在门外等待,确保签约过程的绝对安全和私密。

正是这种“读靠快照,写靠锁,两者自动切换”的机制,让 InnoDB 在高并发下既能保证数据一致性,又能维持出色的性能。

http://www.jsqmd.com/news/486980/

相关文章:

  • TR-069 交互流程开发规范
  • 基于SpringBoot与Android的宠物社区APP设计与实现
  • 2007-2024年上市公司多言寡行数据
  • ADS原理图VIAGND直接生成版图未成功过孔
  • 【第二周】RAG与Agent实战15:模板类的 format 和 invoke 方法深度解析
  • 矩形面积交-进阶题7
  • vue3-signature实现电子签名
  • 【GUI-Agent】阶跃星辰 GUI-MCP 解读---(1)---论文
  • Agentic AI时代程序员必备算法思想详解(附实战案例)
  • MySQL数据库—索引
  • AstrBot+NapCat 打造随时随地可用的 QQ 智能机器人(1)
  • MCP工具粒度的权衡 - yi
  • 解决大模型微调的灾难性遗忘:Nova Forge 数据混合策略工程实践
  • Claude Code 费用与中转api
  • C语言指针概念详解:数组指针与二级指针的本质区别
  • 2026年高端制造视角下的气密性测试仪供应商甄选与竞争力解析 - 深度智识库
  • P8627 [蓝桥杯 2015 省 A] 饮料换购【模拟+数学】
  • 第一个Java文件!Hello,world! - Kight
  • 银河麒麟桌面操作系统 V11 来袭!硬核架构 + 全维安全
  • kubernetes知识点汇总13-18
  • 2026年气密性测试仪选购指南:趋势解析与五大优质厂商深度评测 - 深度智识库
  • 无需服务器!Windows 部署 OpenClaw,打造私人 AI助手
  • 2026年气密性检测设备厂家实力推荐高端制造质检解决方案优选指南 - 深度智识库
  • 论文排版之添加图片、表格、公式的题注
  • 文化课期间复建 OI 记录
  • 第1章 线性代数的本源:线性、结构与系统思维
  • 基于 libhv 实现多路径 WebSocket 服务器:设计与实战
  • 最近在搞AUTOSAR项目,发现生成RTE和配置协议栈这两个环节真能让人头秃。今天就带大家手搓点实战经验,顺便聊聊那些藏在XML背后的骚操作
  • 2026春季下学期第三周
  • 入门必懂:AI Agent核心概念拆解——从“是什么”到“能做什么”(2026智能体开发系列·第2篇)