MySQL 高并发核心:MVCC 底层原理彻底讲透,一篇吃透面试 + 实战 + 性能优化

news2026/4/7 6:50:59
前言为什么你总搞不懂 MVCC却又处处离不开它只要做 MySQL 开发、面试、调优MVCC 绝对是绕不开的大山。有人背了三遍概念一到面试就被问懵什么是脏读、不可重复读、幻读RC 和 RR 到底差在哪ReadView 怎么判断可见性为什么长事务能把数据库拖崩MVCC 和事务到底是不是一回事更扎心的是线上并发一高SQL 一卡问题最后往往都指向 MVCC。很多教程要么太浅只说 “读写不阻塞”要么太学术满篇公式看得人头大。今天这篇我用最通俗、最落地、最吸粉的方式把 MVCC 从底层原理、隐藏字段、版本链、ReadView、隔离级别、和事务的区别、到实战使用、性能提升一次性彻底讲透。无论你是面试突击、业务开发、DBA 运维看完这篇MVCC 这块直接封神。一、先搞懂MVCC 到底是个啥解决了什么痛点MVCC全称Multi-Version Concurrency Control多版本并发控制。听着高大上其实逻辑非常朴素一份数据存多个版本。你读旧的我写新的咱俩互不干扰。在没有 MVCC 的年代数据库靠锁过日子读要加 S 锁写要加 X 锁读阻塞写写阻塞读结果就是高并发下全是锁等待接口超时死锁频发数据库直接跪。MVCC 就是来破局的。它的核心能力就三件事读不加锁读写不阻塞实现事务隔离避免脏读、不可重复读在快照读层面避免幻读大幅提升并发能力一句话总结MVCC 用空间换时间用版本换并发。什么是脏读、不可重复读面试必问一看就懂在讲 MVCC 之前必须先搞懂并发事务带来的三大问题因为 MVCC 存在的意义就是为了解决它们。1. 什么是脏读脏读一个事务读到了另一个事务 “还没提交” 的数据。场景举例事务 A 把用户余额从 100 改成 200但还没提交事务 B 查到余额是 200拿去做业务逻辑结果事务 A 异常回滚了余额变回 100事务 B 之前读到的 200 就是脏数据这种情况就叫脏读。脏读本质是读到了未提交数据业务完全不可接受。2. 什么是不可重复读不可重复读一个事务内同一条 SQL 多次执行结果不一样。场景举例事务 A 第一次查询余额100事务 B 修改余额为 200 并提交事务 A 再查一次余额200同一个事务内两次查询结果不一致这就叫不可重复读。它比脏读轻但会导致事务内部逻辑错乱尤其在统计、扣款、对账场景非常危险。3. 什么是幻读幻读一个事务内按条件查询前后结果集行数不一样像出现了 “幻觉”。场景举例事务 A 查询age18的数据共 10 条事务 B 插入一条age18并提交事务 A 再查变成 11 条多出的一行就叫幻行这种现象就是幻读。二、MVCC 底层基石每行数据都藏着三个秘密字段想真正吃透 MVCC必须先看懂 InnoDB 对每一行数据动的手脚。你看不到但它真实存在。2.1 三条隐藏字段InnoDB 聚簇索引的每一行默认带三列DB_TRX_ID6 字节最后插入 / 更新这条数据的事务 ID。全局自增用来判断版本新旧。DB_ROLL_PTR7 字节回滚指针指向 undo log 里的历史版本。无数个版本靠它串成一条链叫版本链。DB_ROW_ID6 字节隐式主键没建主键时 InnoDB 自动生成。和 MVCC 逻辑关系不大知道就行。2.2 版本链 Undo Log 是怎么形成的很多人以为更新是 “覆盖数据”大错特错。InnoDB 更新流程真实样子对旧数据加行锁把旧数据写入 undo log生成一条新数据DB_TRX_ID 设为当前事务 ID新数据的 DB_ROLL_PTR 指向 undo log 里的旧数据索引叶子节点指向最新记录最终形成新记录 → 旧记录 → 更旧记录 → ……这就是版本链。查询时就从最新版本开始顺着链往前找直到找到 “对当前事务可见” 的那一条。三、重点澄清MVCC 和事务到底有什么区别与联系这是面试最爱挖坑、90% 人混淆的地方MVCC 是事务吗事务靠 MVCC 实现吗今天一次性说清楚。3.1 本质区别层级完全不同事务逻辑层概念应用直接用保证一组 SQL 原子执行。MVCC存储引擎底层机制对应用透明负责无锁并发读。目标不同事务目标保证 ACID要么全成功要么全回滚。MVCC 目标在保证隔离性的前提下解决脏读、不可重复读提升并发。功能范围不同事务管原子性、一致性、隔离性、持久性。MVCC 只管多版本、可见性判断、快照读的隔离。MVCC 不管崩溃恢复不管持久化不管回滚本身。能否独立存在事务可以脱离 MVCC 存在纯锁也能实现事务。MVCC 绝对不能脱离事务存在。没有事务 ID、没有活跃事务集合、没有 undo 生命周期MVCC 直接废了。生命周期不同事务begin → commit/rollback结束就消失。MVCC 版本跨多个事务存在直到没人用才被 purge 清理。3.2 内在联系MVCC 是事务隔离性的核心实现方式RC、RR 隔离级别主要靠 MVCC 支撑。事务为 MVCC 提供运行环境事务 ID、ReadView、undo log、提交策略都是 MVCC 的基础。InnoDB 事务 MVCC 锁 redo/undoMVCC 做无锁读锁做写写互斥、当前读互斥redo 保证持久化undo 保证原子性 MVCC 版本长事务坑事务更坑 MVCC事务持有锁太久 → ReadView 不释放 → 版本无法清理 → 版本链爆炸 → 查询变慢。一句话记死事务是功能MVCC 是实现高性能事务的核心技术。四、ReadViewMVCC 的灵魂可见性判断规则一个事务到底能看见哪个版本全靠ReadView一致性视图说了算。4.1 ReadView 里存了什么四个关键字段m_ids生成视图时所有正在活跃、没提交的事务 ID 集合。min_trx_idm_ids 里最小的事务 ID。max_trx_id生成视图时下一个要分配的事务 ID。creator_trx_id当前事务自己的 ID。4.2 可见性判断四步法面试必考从最新版本开始依次判断如果版本的 trx_id 自己的 ID→ 自己改的可见。如果版本 trx_id min_trx_id→ 这条数据在我启动前就提交了可见。如果版本 trx_id ≥ max_trx_id→ 这条数据是我启动后才生成的不可见。如果在 min 和 max 之间不在 m_ids 里 → 已经提交 →可见在 m_ids 里 → 还没提交 →不可见不可见就顺着回滚指针往前找直到找到可见版本或者找不到。这就是 MVCC 最核心的算法。看懂这一段你已经超过 60% 后端开发。五、RC 和 RR 的本质区别就差一个 ReadView面试必问RC、RR 隔离级别底层到底差在哪答案极其简单什么时候生成 ReadView。5.1 RR可重复读MySQL 默认事务启动时生成一次 ReadView整个事务期间从头到尾只用这一个视图所以多次查询结果一模一样 →避免不可重复读快照读不会出现幻读5.2 RC读已提交每执行一条普通 SELECT都生成新的 ReadView每次都能看到最新已提交数据只避免脏读允许不可重复读但更轻量、并发更高、锁更少5.3 幻读到底解决没很多人被搞晕快照读普通 selectMVCC 解决幻读当前读for update /update靠 next-key lock 解决幻读MVCC 不是万能的它只管快照读。六、快照读 vs 当前读90% 人用错 MVCC一个超级关键的认知MVCC 只作用于快照读当前读和 MVCC 无关6.1 快照读MVCC 主场普通查询sqlSELECT * FROM t WHERE id1;不加锁读写不阻塞高并发神器完全走 MVCC 多版本6.2 当前读锁主场这些语句都是当前读SELECT ... FOR UPDATESELECT ... LOCK IN SHARE MODEUPDATE / DELETE / INSERT它们读取最新已提交数据加行锁、gap lock、next-key lock和 MVCC 无关会阻塞会竞争所以记住MVCC 优化读锁保护写。缺一不可。七、Undo Log Purge 线程MVCC 的 “清洁工”版本不能永远留着谁来清理undo log 存历史版本purge 线程负责垃圾回收7.1 Undo Log 分两种insert undo只用来回滚事务提交就能删。update undo给 MVCC 提供历史版本必须等所有 ReadView 不用了才能删。7.2 Purge 线程是干嘛的清理标记删除的记录清理无用历史版本回收表空间如果 purge 跟不上后果ibd 文件暴涨版本链越来越长查询从 1ms 变 1s数据库越来越卡而导致 purge 失效的元凶只有一个长事务。八、为什么说长事务是 MVCC 天敌线上血泪教训长事务 开启事务后很久不提交。它对 MVCC 的杀伤是毁灭性的ReadView 长期不释放历史版本无法清理undo log 疯狂膨胀版本链巨长查询遍历成本爆炸锁持有时间长死锁、超时满天飞线上真实案例一个 2 小时未提交事务直接把 undo 干到 50GB核心接口全面超时。铁律任何业务都必须禁止长事务查看长事务 SQLsqlSELECT * FROM information_schema.innodb_trx WHERE TIME_TO_SEC(TIMEDIFF(NOW(), trx_started)) 60;九、如何正确使用 MVCC 大幅提升性能实战干货懂原理不算牛能用 MVCC 把系统性能打上去才是真牛。9.1 合理选择隔离级别订单、支付、交易核心RR可重复读避免脏读 不可重复读一致性最强高并发、后台系统、非金融RC读已提交只避免脏读允许不可重复读性能更好RC 优势锁范围更小更少 gap lockpurge 更及时并发更高9.2 尽量用快照读少加锁能不加锁就不加锁sql-- 推荐MVCC 无锁 SELECT name FROM user WHERE id1; -- 不推荐没必要加锁 SELECT name FROM user WHERE id1 FOR UPDATE;9.3 绝对禁止长事务事务内不要调 HTTP、RPC、第三方接口不要 sleep不要开着事务去等人工操作事务执行时间尽量 1s9.4 避免大事务、批量更新拆小大事务会生成巨量版本拖垮 purge 和查询。9.5 优先走主键、唯一索引MVCC 从聚簇索引开始遍历主键查询最快。9.6 监控 purge 状态plaintextSHOW ENGINE INNODB STATUS;看History list length过高说明 purge 阻塞。十、MVCC 性能提升到底强在哪为什么用上 MVCC并发能明显提升彻底消除读阻塞写、写阻塞读读旧版写新版互不排队。90% 查询无锁锁竞争大幅下降CPU 不用频繁等待、唤醒吞吐量暴涨。死锁概率明显降低锁越少冲突越少死锁越少。高并发读场景性能提升几倍到十几倍读多写少系统MVCC 就是神器。IO 更低、内存更稳无锁竞争系统抖动更小。十一、面试高频误区背会直接加分MVCC 可以替代锁错。MVCC 只管快照读写和当前读必须靠锁。MVCC 完全解决幻读错。只解决快照读幻读当前读靠 next-key lock。事务一提交版本立刻删除错。要等所有 ReadView 不再引用才会被 purge。所有 SELECT 都是快照读错。加锁查询、串行化隔离级别都不是。MVCC 实现了事务的 ACID错。MVCC 只参与隔离性不管原子性、持久性。RC 已经解决不可重复读错。RC 只解决脏读不解决不可重复读RR 才解决。十二、总结看完这一段你就彻底通透了MVCC 是 InnoDB 高并发的灵魂核心逻辑其实非常清晰事务是逻辑功能MVCC 是底层实现技术脏读读到未提交数据不可重复读同一事务多次查询结果不一致每行数据靠隐藏字段 undo log 形成版本链ReadView 决定可见性是 MVCC 核心RR 共用一个视图解决不可重复读RC 每次查询新建视图只解决脏读快照读无锁当前读加锁长事务是 MVCC 最大杀手合理使用 MVCC能让系统并发能力大幅提升从面试到实战从原理到性能这一篇足够你吃透 MVCC。下次再有人问你 MVCC你可以直接笑着讲完整条链路。欢迎关注我后续会持续输出✅ MySQL 高频面试题 ✅ MySQL 性能优化实战✅ Windows Linux 运维干货✅ 后端开发、高并发、数据库调优系列教程✅ 不定期分享可直接落地的配置模板与脚本

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2491705.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…