MySQL MVCC 机制详解

MySQL MVCC 机制详解

1. MVCC 基本概念

MVCC 是一种并发控制的方法,主要用于数据库管理系统,允许多个事务同时读取数据库中的同一个数据项,而不需要加锁,从而提高了数据库的并发性能。

┌─────────────────────────────────────┐
│         MVCC 的核心思想              │
│                                     │
│  对数据进行修改操作时,不会直接覆盖数据,│
│  而是创建一个新版本,让读操作可以看到   │
│  修改前的数据                        │
└─────────────────────────────────────┘

2. MVCC 在 InnoDB 中的实现

InnoDB 引擎下 MVCC 的实现主要基于以下几个关键概念:

2.1 隐藏字段

InnoDB 为每一行记录添加了三个隐藏字段:

┌───────────────────────────────────────────────────────┐
│                   InnoDB 行记录结构                     │
├───────────┬───────────┬───────────┬───────────────────┤
│ DB_TRX_ID │ DB_ROLL_PTR│ DB_ROW_ID │ 实际数据列(可见部分) │
│ 事务ID    │ 回滚指针   │ 行ID(可选) │                    │
└───────────┴───────────┴───────────┴───────────────────┘
  • DB_TRX_ID:创建或最后修改该记录的事务ID
  • DB_ROLL_PTR:指向 undo log 的指针,用于数据回滚
  • DB_ROW_ID:如果没有主键,InnoDB 会自动生成的行ID

2.2 undo log 版本链

当一行记录被修改时,InnoDB 会将旧版本的记录写入 undo log,并在当前记录中通过回滚指针指向这个 undo log 记录,形成一个版本链。

┌──────────────────────────────────────────────────────────────┐
│                       版本链示意图                            │
│                                                              │
│  最新记录                                                     │
│  ┌─────────┬─────────┬─────────┬───────────┐                 │
│  │TRX_ID=30│ROLL_PTR │ROW_ID   │name="张三" │                 │
│  └─────────┴─────────┴─────────┴───────────┘                 │
│      │                                                       │
│      ▼ 回滚指针指向                                           │
│  Undo Log 1                                                  │
│  ┌─────────┬─────────┬─────────┬───────────┐                 │
│  │TRX_ID=20│ROLL_PTR │ROW_ID   │name="李四" │                 │
│  └─────────┴─────────┴─────────┴───────────┘                 │
│      │                                                       │
│      ▼ 回滚指针指向                                           │
│  Undo Log 2                                                  │
│  ┌─────────┬─────────┬─────────┬───────────┐                 │
│  │TRX_ID=10│ROLL_PTR │ROW_ID   │name="王五" │                 │
│  └─────────┴─────────┴─────────┴───────────┘                 │
│                                                              │
└──────────────────────────────────────────────────────────────┘

2.3 ReadView

ReadView 是 MVCC 实现的关键机制,它决定了当前事务能够看到哪个版本的数据。ReadView 包含以下重要信息:

  • m_ids:当前系统中活跃的事务ID集合
  • min_trx_id:活跃的最小事务ID
  • max_trx_id:系统中将要分配给下一个事务的ID
  • creator_trx_id:创建该 ReadView 的事务ID
┌──────────────────────────────────────────────┐
│               ReadView 示意图                 │
│                                              │
│  ┌────────────────────────────────────────┐  │
│  │ m_ids: [10, 20, 30]                    │  │
│  │ min_trx_id: 10                         │  │
│  │ max_trx_id: 40                         │  │
│  │ creator_trx_id: 25                     │  │
│  └────────────────────────────────────────┘  │
│                                              │
└──────────────────────────────────────────────┘

3. MVCC 可见性判断规则

当一个事务要读取一行记录时,它会根据 ReadView 和记录的 DB_TRX_ID 来判断该版本的记录是否可见:

┌─────────────────────────────────────────────────────────────────┐
│                  MVCC 可见性判断流程图                           │
│                                                                 │
│   ┌───────────────┐                                             │
│   │ 开始判断可见性 │                                             │
│   └───────┬───────┘                                             │
│           ▼                                                     │
│   ┌───────────────────────────────┐     是     ┌───────────┐     │
│   │ trx_id == creator_trx_id?    ├────────────►│ 可见     │     │
│   └───────────┬───────────────────┘            └───────────┘     │
│               │ 否                                               │
│               ▼                                                 │
│   ┌───────────────────────────────┐     是     ┌───────────┐     │
│   │ trx_id < min_trx_id?         ├────────────►│ 可见     │     │
│   └───────────┬───────────────────┘            └───────────┘     │
│               │ 否                                               │
│               ▼                                                 │
│   ┌───────────────────────────────┐     是     ┌───────────┐     │
│   │ trx_id >= max_trx_id?        ├────────────►│ 不可见   │     │
│   └───────────┬───────────────────┘            └───────────┘     │
│               │ 否                                               │
│               ▼                                                 │
│   ┌───────────────────────────────┐     是     ┌───────────┐     │
│   │ trx_id 在 m_ids 中?           ├────────────►│ 不可见   │     │
│   └───────────┬───────────────────┘            └───────────┘     │
│               │ 否                                               │
│               ▼                                                 │
│               ┌───────────┐                                     │
│               │ 可见      │                                     │
│               └───────────┘                                     │
└─────────────────────────────────────────────────────────────────┘

4. 不同隔离级别下的 MVCC 行为

MVCC 主要在 READ COMMITTED 和 REPEATABLE READ 隔离级别下工作:

┌─────────────────────────────────────────────────────────────────┐
│               不同隔离级别的 ReadView 创建时机                    │
│                                                                 │
│  ┌────────────────────┐        ┌─────────────────────────────┐  │
│  │    READ COMMITTED  │        │      REPEATABLE READ       │  │
│  ├────────────────────┤        ├─────────────────────────────┤  │
│  │                    │        │                             │  │
│  │ 每次SELECT时创建新的 │        │ 事务开始时创建一次ReadView   │  │
│  │ ReadView           │        │ 之后所有查询复用这个ReadView │  │
│  │                    │        │                             │  │
│  └────────────────────┘        └─────────────────────────────┘  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

4.1 READ COMMITTED

  • 每次SELECT都会创建一个新的ReadView
  • 可以看到其他已提交事务的更改
  • 解决了脏读问题,但可能出现不可重复读

4.2 REPEATABLE READ(MySQL默认)

  • 在事务开始时创建一个ReadView,之后的查询都复用这个ReadView
  • 在整个事务过程中,对已经读取的数据,其他事务的更新对当前事务不可见
  • 解决了不可重复读问题

5. MVCC的实际例子

假设我们有一个简单的表格和以下操作序列:

创建表: CREATE TABLE user(id INT PRIMARY KEY, name VARCHAR(20));
初始数据: INSERT INTO user VALUES(1, '小明');

接下来,有三个事务同时操作这条记录:

┌─────────────────────────────────────────────────────────────────┐
│                       事务并发执行示例                            │
│                                                                 │
│  时间 │ 事务A(trx_id=10)  │ 事务B(trx_id=20)  │ 事务C(trx_id=30)  │
│ ─────┼──────────────────┼──────────────────┼────────────────── │
│  t1  │ BEGIN;           │                  │                   │
│  t2  │                  │ BEGIN;           │                   │
│  t3  │                  │                  │ BEGIN;            │
│  t4  │ SELECT * FROM    │                  │                   │
│      │ user WHERE id=1; │                  │                   │
│      │ 结果: '小明'      │                  │                   │
│  t5  │                  │ UPDATE user SET  │                   │
│      │                  │ name='小红'       │                   │
│      │                  │ WHERE id=1;      │                   │
│  t6  │                  │ COMMIT;          │                   │
│  t7  │ SELECT * FROM    │                  │                   │
│      │ user WHERE id=1; │                  │                   │
│      │ 结果(RC): '小红'  │                  │                   │
│      │ 结果(RR): '小明'  │                  │                   │
│  t8  │                  │                  │ UPDATE user SET   │
│      │                  │                  │ name='小黑'        │
│      │                  │                  │ WHERE id=1;       │
│  t9  │                  │                  │ COMMIT;           │
│ t10  │ SELECT * FROM    │                  │                   │
│      │ user WHERE id=1; │                  │                   │
│      │ 结果(RC): '小黑'  │                  │                   │
│      │ 结果(RR): '小明'  │                  │                   │
│ t11  │ COMMIT;          │                  │                   │
└─────────────────────────────────────────────────────────────────┘

版本链变化过程:

初始状态:
┌─────────┬─────────┬─────────┬───────────┐
│TRX_ID=1 │ROLL_PTR │ROW_ID   │name="小明" │
└─────────┴─────────┴─────────┴───────────┘事务B更新后:
┌─────────┬─────────┬─────────┬───────────┐
│TRX_ID=20│ROLL_PTR │ROW_ID   │name="小红" │
└─────────┴─────────┴─────────┴───────────┘│▼
┌─────────┬─────────┬─────────┬───────────┐
│TRX_ID=1 │ROLL_PTR │ROW_ID   │name="小明" │
└─────────┴─────────┴─────────┴───────────┘事务C更新后:
┌─────────┬─────────┬─────────┬───────────┐
│TRX_ID=30│ROLL_PTR │ROW_ID   │name="小黑" │
└─────────┴─────────┴─────────┴───────────┘│▼
┌─────────┬─────────┬─────────┬───────────┐
│TRX_ID=20│ROLL_PTR │ROW_ID   │name="小红" │
└─────────┴─────────┴─────────┴───────────┘│▼
┌─────────┬─────────┬─────────┬───────────┐
│TRX_ID=1 │ROLL_PTR │ROW_ID   │name="小明" │
└─────────┴─────────┴─────────┴───────────┘

6. MVCC的优缺点

优点:

  • 提高并发性能,读不阻塞写,写不阻塞读
  • 解决了读-写冲突问题
  • 支持事务的隔离级别实现

缺点:

  • 需要额外的存储空间维护旧版本数据
  • 需要定期清理过时的旧版本数据
  • 实现较为复杂

总结

MVCC 是 MySQL InnoDB 存储引擎中实现高并发的关键技术,通过在每行记录后面保存两个隐藏的列(事务ID和回滚指针)来实现的。它能够让不同事务的读、写操作并发执行,同时保证事务的隔离性。根据不同的隔离级别,MySQL 会采用不同的策略来创建和维护 ReadView,从而影响数据的可见性。

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

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

相关文章

Model Context Protocol (MCP) - 尝试创建和测试一下MCP Server

1.简单介绍 MCP是Model Context Protocol的缩写&#xff0c;是Anthropic开源的一个标准协议。MCP使得大语言模型可以和外部的数据源&#xff0c;工具进行集成。当前MCP在社区逐渐地流行起来了。同时official C# SDK(仓库是csharp-sdk) 也在不断更新中&#xff0c;目前最新版本…

(三)行为模式:12、访问者模式(Visitor Pattern)(C++示例)

目录 1、访问者模式含义 2、访问者模式的UML图学习 3、访问者模式的应用场景 4、访问者模式的优缺点 5、访问者模式C实现的实例 1、访问者模式含义 访问者模式&#xff08;Visitor Pattern&#xff09;是一种行为型设计模式&#xff0c;它允许将一个作用于某对象结构中的各…

windows安卓子系统wsa隐藏应用列表的安装激活使用

Windows 11 安卓子系统应用部署全攻略 windows安卓子系统wsa隐藏应用列表的安装激活使用|过检测核心前端 在 Windows 11 系统中&#xff0c;安卓子系统为用户带来了在电脑上运行安卓应用的便利。经过一系列的操作&#xff0c;我们已经完成了 Windows 11 安卓子系统的底层和前端…

Elasticsearch 集群搭建

一、集群规划 1.1 节点角色规划 节点类型配置要求推荐数量Master节点低磁盘、中等CPU/内存3&#xff08;奇数防止脑裂&#xff09;Data节点高磁盘、高内存、多核CPU根据数据量扩展Coordinating节点高CPU/内存、低磁盘2&#xff08;可选&#xff09; 1.2 硬件建议 内存&…

React 响应事件

开发环境&#xff1a;Reacttsantd 使用 React 可以在 JSX 中添加 事件处理函数。其中事件处理函数为自定义函数&#xff0c;它将在响应交互&#xff08;如点击、悬停、表单输入框获得焦点等&#xff09;时触发。 学习内容 1.编写事件处理函数的不同方法 2.如何从父组件传递事件…

SQL基础入门:从CRUD到JOIN再到索引(通俗易懂版)

一、为什么需要SQL&#xff1f; 想象你在管理一个图书馆&#xff1a; 传统方法&#xff1a;手动记录每本书的位置、借阅者、归还日期SQL方法&#xff1a;用数据库系统自动管理&#xff0c;快速查询《Java编程思想》在哪个书架 SQL&#xff08;Structured Query Language&…

MINIQMT学习课程Day11

现在开始进行策略的交易买卖分析&#xff1a; 还是之前的步骤&#xff0c;打开qmt&#xff0c;选择独立交易&#xff0c; 之后使用pycharm&#xff0c;编写py文件 导入包&#xff1a; import time, datetime, traceback, sys from xtquant import xtdata from xtquant.xttr…

# 实时人脸性别与年龄识别:基于OpenCV与深度学习模型的实现

实时人脸性别与年龄识别&#xff1a;基于OpenCV与深度学习模型的实现 在当今数字化时代&#xff0c;计算机视觉技术正以前所未有的速度改变着我们的生活与工作方式。其中&#xff0c;人脸检测与分析作为计算机视觉领域的重要分支&#xff0c;已广泛应用于安防监控、智能交互、…

Python Cookbook-5.14 给字典类型增加排名功能

任务 你需要用字典存储一些键和“分数”的映射关系。你经常需要以自然顺序(即以分数的升序)访问键和分数值&#xff0c;并能够根据那个顺序检查一个键的排名。对这个问题&#xff0c;用dict 似乎不太合适。 解决方案 我们可以使用 dict 的子类&#xff0c;根据需要增加或者重…

十四种逻辑器件综合对比——《器件手册--逻辑器件》

目录 逻辑器件 简述 按功能分类 按工艺分类 按电平分类 特殊功能逻辑器件 应用领域 详尽阐述 1 逻辑门 一、基本概念 二、主要类型 三、实现方式 四、应用领域 2 反相器 工作原理 基本功能 主要应用 常见类型 特点 未来发展趋势 3 锁存器 基本概念 工作原理 主要类型…

如何更改wsl2中的ubuntu默认安装位置

先前的一篇文章提到了如何更改wsl里面ubuntu的home目录&#xff0c;wsl装ubuntu的home目录在哪&#xff0c;如何更改home&#xff1f;_wsl安装的ubuntu在哪里-CSDN博客 这次是要更改wsl中ubuntu的安装目录&#xff0c;毕竟默认安装到c盘下会占用不少空间的。 从微软商店get后…

最近在工作中感受到了设计模式的重要性

之前了解设计模式&#xff1a;只是应付一下面试 在之前一年多的工作中也没遇到使用场景 最近在搭建验证环境的时候&#xff0c;才发现这玩意这么重要 首先是设计模式的使用场景一定是在很复杂繁琐的场景下进行的 之所以说是复杂/繁琐的场景&#xff0c;因为一些场景也许逻辑不难…

Python深度学习基础——卷积神经网络(CNN)(PyTorch)

CNN原理 从DNN到CNN 卷积层与汇聚 深度神经网络DNN中&#xff0c;相邻层的所有神经元之间都有连接&#xff0c;这叫全连接&#xff1b;卷积神经网络 CNN 中&#xff0c;新增了卷积层&#xff08;Convolution&#xff09;与汇聚&#xff08;Pooling&#xff09;。DNN 的全连接…

Linux 第三讲 --- 基础指令(三)

前言&#xff1a; 在前面我们已经讲了有十几个Linux的基础指令&#xff0c;今天我们再补充几个常用的基础指令&#xff0c;为后面的学习做准备 。 目录 前言&#xff1a; 一、两个与时间相关的指令 1.date指令 演示 &#xff1a; 时间戳 设置时间 2、cal指令 演示&#x…

基于SiamFC的红外目标跟踪

基于SiamFC的红外目标跟踪 1,背景与原理2,SiamFC跟踪方法概述2.1 核心思想2.2 算法优势3,基于SiamFC的红外跟踪代码详解3.1 网络定义与交叉相关模块3.2 SiamFC 跟踪器实现3.3 主程序:利用 OpenCV 实现视频跟踪4,总结与展望在红外监控、无人机防御以及低光照场景中,红外图…

Odoo 部署本地 把現時的excel計算表格部署上odoo 教程

要将现有的 Excel 计算表格部署到 Odoo 平台上&#xff0c;您可以按照以下步骤进行操作&#xff1a; 将 Excel 表格中的数据转移到 Odoo 模块中&#xff1a;首先&#xff0c;您需要将 Excel 表格中的数据导出为 CSV 格式&#xff0c;然后可以使用 Odoo 的数据导入功能将这些数据…

KWDB创作者计划—KWDB认知引擎:数据流动架构与时空感知计算的范式突破

引言&#xff1a;数据智能的第三范式 在数字化转型进入深水区的2025年&#xff0c;企业数据系统正面临三重悖论&#xff1a;数据规模指数级增长与实时决策需求之间的矛盾、多模态数据孤岛与业务连续性要求之间的冲突、静态存储范式与动态场景适配之间的鸿沟。KWDB&#xff08;K…

C语言 数据结构 【栈】动态模拟实现

引言 动态模拟实现栈的各个接口 一、栈的概念与结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;LastInFirstOut…

Python itertools模块的groupby函数介绍

itertools.groupby 是 Python 标准库 itertools 模块中的一个函数&#xff0c;它的主要功能是对可迭代对象中相邻的相同元素进行分组。 itertools.groupby(iterable, keyNone) 函数 作用&#xff1a; 将连续的&#xff08;相邻的&#xff09;相同元素分组&#xff0c;返回 (…

Python实例题:使用Python生成分形图片

目录 Python实例题 题目 题目分析 需求理解 关键知识点 实现思路分析 代码实现 代码解释 mandelbrot 函数&#xff1a; 设置复平面区域和图像参数&#xff1a; 计算分形数据&#xff1a; 绘图展示&#xff1a; 运行思路 Python实例题 题目 使用Python生成分形图…