01_MVCC(多版本并发机制)

devtools/2024/10/24 0:16:07/

MVCC_0">MVCC多版本并发机制

文章目录

    • MVCC多版本并发机制
        • 简介
        • 工作原理
          • 主要组件
        • 事务隔离级别与 MVCC
        • 实现方式
          • 快照读(Snapshot Read)
          • 当前读(Current Read)
          • 版本链管理
        • MVCC 的优缺点
          • 优点
          • 缺点
        • 示例
        • 总结
        • 延伸

简介

MySQL 中的 MVCC(Multi-Version Concurrency Control,多版本并发控制)是一种用于实现高并发、低冲突数据访问的技术。它通过维护数据的多个版本来实现读写操作的并发控制,它允许多个事务同时对同一数据进行读取和修改,而不会互相干扰,从而实现了非阻塞的读操作,降低了写操作的冲突。MVCC 在 InnoDB 存储引擎中得到了实现,是实现 ACID(原子性、一致性、隔离性、持久性)属性中隔离性的关键。

在并发场景下,可能出现三种情况:读-读并发读-写并发写-写并发。在没有写的情况下 读-读并发 是不会出现问题的,而 写-写并发 这种情况比较常用的就是通过加锁的方式实现。那么,读-写并发 则可以通过 MVCC 的机制解决。


工作原理

MVCC 的基本思想是通过存储每行数据的多个版本,实现并发控制,允许读操作和写操作并发执行,避免大部分加锁操作。

主要组件
  1. 隐藏列
    • trx_id:每行记录的创建或最后一次修改该行数据的事务ID。
    • roll_pointer:指向该行数据的上一个版本的指针,用于形成版本链。
  2. 回滚日志(Undo Log)
    • 每次事务修改数据时,旧版本数据会被保存在回滚日志中,形成一个版本链。
    • 用于事务回滚和快照读时的数据读取。
  3. 读视图(Read View)
    • 事务启动时生成的快照视图,用于确定在事务期间可见的数据版本。
    • 确保在可重复读隔离级别下读取到一致性数据。

MVCC_29">事务隔离级别与 MVCC

不同的事务隔离级别对 MVCC 的行为有不同的要求:

  1. 读未提交(Read Uncommitted)
    • 不使用 MVCC,读取未提交的数据,可能会出现脏读。
  2. 读已提交(Read Committed)
    • 每次读取最新提交的数据版本(即一个事务中的每一次 SELECT 都会重新获取一次 ReadView),不使用快照视图,可能会出现不可重复读。
  3. 可重复读(Repeatable Read)
    • 使用 MVCC,事务在启动时创建一致性视图,读取该视图的快照数据(即一个事务中只有第一次 SELECT 会读取 ReadView),避免不可重复读和幻读问题。
  4. 串行化(Serializable)
    • 强制事务串行执行,通过加锁实现,不使用 MVCC

实现方式
快照读(Snapshot Read)

​ 快照读是指读取一致性视图中的数据,不加锁。具体流程如下:

  1. 事务启动:在事务启动时,InnoDB 创建一个一致性视图(Read View),记录当前系统中活跃事务的 ID。
  2. 读取数据:读取数据时,根据隐藏列 trx_idroll_pointer 形成的版本链,查找符合当前一致性视图的数据版本。
  3. 返回结果:返回符合一致性视图的数据版本,确保读取的是事务启动时的快照数据。
-- 事务1:启动事务
START TRANSACTION;
-- 快照读,读取一致性视图中的数据
SELECT * FROM example WHERE id = 1;
当前读(Current Read)

​ 当前读是指读取最新的数据版本并加锁,确保数据的一致性。具体操作包括:

  • SELECT … FOR UPDATE:读取数据并加排他锁,阻止其他事务的读写操作。
  • SELECT … LOCK IN SHARE MODE:读取数据并加共享锁,允许其他事务的读操作,但阻止写操作。
  • INSERT、UPDATE、DELETE:对数据进行修改,必须读取最新版本的数据并加锁。
-- 事务1:启动事务
START TRANSACTION;
-- 当前读,加排他锁
SELECT * FROM example WHERE id = 1 FOR UPDATE;

​ 可以说,快照读是 MVCC 实现的基础,而当前读是悲观锁实现的基础

版本链管理

​ 每次数据修改操作时,InnoDB 会创建一个新版本的记录,并通过 roll_pointer 指向旧版本,形成版本链。

-- 事务2:启动事务并更新数据
START TRANSACTION;
UPDATE example SET value = 'B' WHERE id = 1;
COMMIT;

在上述操作中,InnoDB 会将旧版本的 value = 'A' 存储在回滚日志中,新版本的 value = 'B' 记录当前事务ID,并指向旧版本。


MVCC__93">MVCC 的优缺点
优点
  1. 高并发性能:读操作无需加锁,减少锁争用,提高系统并发性能。
  2. 数据一致性:通过一致性视图,实现可重复读和读已提交隔离级别下的数据一致性,避免脏读和不可重复读问题。
缺点
  1. 存储开销:维护多个版本的数据和回滚日志,增加存储需求。
  2. 数据清理:需要定期清理无用的旧版本数据,增加系统维护复杂性。

示例

以下示例展示了 MVCC 在可重复读隔离级别下的工作方式:

-- 创建表并插入数据
CREATE TABLE example (id INT PRIMARY KEY,value VARCHAR(50)
);INSERT INTO example (id, value) VALUES (1, 'A');-- 事务1:启动事务并读取数据
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;
SELECT * FROM example WHERE id = 1; -- 读取数据,创建一致性视图-- 事务2:启动事务并更新数据
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
UPDATE example SET value = 'B' WHERE id = 1;
COMMIT;-- 事务1:再次读取数据
SELECT * FROM example WHERE id = 1; -- 仍然读取旧版本数据 'A'
COMMIT;

在这个示例中,事务1 启动后创建的一致性视图确保其读取的数据在事务期间保持不变,即使事务2 更新了数据。


总结

MySQL 中的 MVCC 机制通过维护数据的多个版本,实现高并发、低冲突的数据访问。它通过隐藏列、回滚日志和一致性视图等机制,在确保数据一致性的同时,提高了系统的并发性能。通过理解 MVCC 的工作原理和实现方式,可以更好地应用和优化 MySQL 数据库


延伸
  1. MVCC 机制中的版本链管理是如何实现的
  2. 快照读是如何实现的(快照如何存储?存储在哪?多个快照存在时怎么读?)

http://www.ppmy.cn/devtools/128303.html

相关文章

负责域名解析的 DNS 服务

DNS(Domain Name System) 服务是和 HTTP 协议一样位于应用层的协议,它提供域名到 IP 地址之间的解析服务

【微信小程序_14_页面导航】

摘要:本文主要介绍了微信小程序的页面导航相关知识,包括定义、实现方式、导航传参等内容。具体如下: (1)导航方式 声明式导航:通过在页面上声明<navigator>导航组件,可实现页面间跳转,包括跳转到 tabBar 页面、非 tabBar 页面和后退导航。 编程式导航:调用小程序的…

Leetcode 1135. 最低成本连通所有城市

1.题目基本信息 1.1.题目描述 想象一下你是个城市基建规划者&#xff0c;地图上有 n 座城市&#xff0c;它们按以 1 到 n 的次序编号。 给你整数 n 和一个数组 conections&#xff0c;其中 connections[i] [x_i, y_i, cost_i] 表示将城市 x_i 和城市 y_i 连接所要的cost_i&…

|人口分析|007_django基于Python的广东省人口流动数据分析2024_92306i61

目录 系统展示 开发背景 代码实现 项目案例 获取源码 博主介绍&#xff1a;CodeMentor毕业设计领航者、全网关注者30W群落&#xff0c;InfoQ特邀专栏作家、技术博客领航者、InfoQ新星培育计划导师、Web开发领域杰出贡献者&#xff0c;博客领航之星、开发者头条/腾讯云/AW…

生成 Excel 表列名称

Excel 大家都用过&#xff0c;它的列名是用字母编号的&#xff0c;A 表示第一列&#xff0c;B 表示第二列&#xff0c;AA 表示第27列&#xff0c;AB 表示第28列等等。 现给定一个数字&#xff0c;如何得到列名称呢。比如输入28&#xff0c;输出 AB。 一开始以为就是一个简单的…

算法笔记day05

目录 1.最小公倍数 2.最长连续的子序列 3.字母收集 1.最小公倍数 求最小公倍数_牛客题霸_牛客网 算法思路&#xff1a; 这就是一道数学题&#xff0c;a,b的最小公倍数 a * b / 最大公约数。 使用辗转相除法&#xff0c;求a&#xff0c;b的最大公约数。 #include <iostre…

MySQL IN子句:数据顺序与条件顺序不一致情况探究(二)

2. 临时表/派生表的使用 另一个常见的方法是使用一个临时表或派生表&#xff08;也称为子查询&#xff09;来存储IN子句中的 ID&#xff0c;并为这些 ID 添加一个序号&#xff0c;然后在外层查询中根据这个序号进行排序。 使用示例&#xff1a; -- 新建临时表 CTE WITH Rout…

git tag 用法

文章目录 git tag 用法1 概述2 基本用法2.1 创建标签2.1.1 创建轻量级标签2.1.2 创建附注标签 2.2 查看标签2.3 推送标签到远程仓库2.4 删除标签2.5 根据标签拉取代码2.6 注意事项 3 参考资料 git tag 用法 1 概述 git tag 是 Git 版本控制系统中的一个命令&#xff0c;用于为…