首页 > 数据库 >一文彻底弄懂MySQL的MVCC多版本控制器

一文彻底弄懂MySQL的MVCC多版本控制器

时间:2024-10-20 09:09:40浏览次数:1  
标签:事务 快照 MySQL 弄懂 InnoDB 版本 MVCC 数据

InnoDB 的 MVCC(Multi-Version Concurrency Control,多版本并发控制) 是 MySQL 实现高并发事务处理的一种机制。通过 MVCC,InnoDB 可以在高并发环境下支持 事务隔离,并提供 非阻塞的读操作,从而避免锁定所有读操作带来的性能瓶颈。MVCC 允许事务在不加锁的情况下读取数据,保证了性能和一致性。

一、MVCC 基础概念

MVCC 的核心思想是 通过保存数据的多个版本 来支持并发读写。每个事务在读取数据时看到的是某个数据的特定版本,而不是当前最新的值。这个机制依赖于 Undo Log,通过保存每一行记录的历史版本来支持多版本读取。(undolog)

  • 读写分离:MVCC 的主要特性是读取数据不阻塞写操作,写操作也不阻塞读取操作。实现了读写分离,提升了数据库并发处理能力。
  • 时间戳版本管理:每个事务都有一个唯一的 事务 ID(Transaction ID,简称 trx_id,InnoDB 使用事务 ID 来区分数据的不同版本。

在这里插入图片描述

二、MVCC 读操作的两种类型

  1. 快照读(Snapshot Read):读取的是历史版本的数据,是不加锁的普通读取操作。快照读是 MVCC 实现并发读的基础。
    • 比如 SELECT * FROM table WHERE id = 1;,执行的是不加锁的快照读操作。
  2. 当前读(Current Read):读取的是最新版本的数据,并加锁保证数据的一致性和事务隔离。当前读通常伴随着写操作。
    • 比如 SELECT * FROM table WHERE id = 1 FOR UPDATE;,执行的是加锁的当前读操作。

三、MVCC 的工作原理

InnoDB 通过 行版本控制 来管理数据的不同版本。每一行数据在 InnoDB 的行记录中都包含两个隐藏的字段:

  • trx_id:表示最后一次对该行进行修改的事务 ID。
  • roll_pointer:指向该行之前的版本(即 Undo Log 中的记录),通过该指针可以找到数据的历史版本。

1. 事务的开始与结束

  • 每个事务在开始时会生成一个唯一的事务 ID trx_id
  • 在事务读取数据时,InnoDB 会根据 MVCC 机制判断该事务应该看到哪个版本的数据,主要依赖于事务的隔离级别(如 Read CommittedRepeatable Read)。

2. 数据的修改与版本管理

当一个事务修改数据时,InnoDB 会将当前数据的旧版本保存到 Undo Log 中,并在数据行中更新最新的 trx_idroll_pointer。这样即使数据被更新,其他未提交的事务依然可以通过 Undo Log 访问到旧版本的数据。

每行数据都会有多个历史版本,并通过 roll_pointer 链接到这些历史版本。

3. 版本链

版本链是基于 trx_idroll_pointer 建立的,即每次修改数据时,会在 Undo Log 中存储旧版本,行记录会指向旧版本。版本链的结构如下:

最新记录 <-- trx_id_x --trx_id_y --trx_id_z... --> 历史版本

当事务读取数据时,会根据事务的隔离级别、当前事务的 trx_id 以及数据的 trx_id 来决定应该读取哪个版本。

四、MVCC 与事务隔离级别的关系

InnoDB 的 MVCC 机制在不同的事务隔离级别下有不同的行为表现:

  1. Read Committed(读取已提交):事务只会看到其他事务已经提交的版本,每次查询都会读取最新的已提交数据。这种隔离级别下,事务间存在不可重复读问题。
    • 每次查询时,InnoDB 都会返回当前已经提交的最新版本数据。
  2. Repeatable Read(可重复读,MySQL 默认隔离级别):事务在整个过程中看到的是同一个版本快照的数据,即便有其他事务提交了新的数据,当前事务依然看到自己开始时的一致性快照。
    • 事务开始时,InnoDB 会为事务创建一个 一致性视图(consistent view),之后的所有查询都会返回该视图中的数据,保证了可重复读。

隔离级别与 MVCC 读方式的关系

  • Read Committed:每次读取都基于当前已经提交的最新版本,因此快照读是每次返回最新的数据。
  • Repeatable Read:快照读总是基于事务启动时的版本快照,因此即便其他事务提交了新的数据,当前事务依然看到的是旧数据,直到它自己提交。

五、MVCC 的实现细节

1. 事务 ID 与版本控制

InnoDB 使用事务 ID(trx_id)来区分不同事务对数据的修改。每次修改都会将当前事务的事务 ID 记录在该行数据的 trx_id 字段中。通过事务 ID,InnoDB 可以判断当前事务是否能够看到某一行数据的特定版本。

2. 一致性视图

一致性视图(Consistent Read View)是指当前事务只能看到事务启动时的数据快照,除非事务使用的是当前读。InnoDB 会根据当前事务的事务 ID 和一致性视图来确定读取哪一个版本的数据。

  • 对于快照读:根据事务的开始时间戳、其他事务的提交情况,来判断该事务看到的是哪个版本的数据。
  • 对于当前读:必须是最新的数据,InnoDB 会为当前事务加锁,防止其他事务修改或读取。

3. Undo Log 与 Rollback Segment

当一个事务修改数据时,InnoDB 会将原始的数据版本存入 Undo Log 中,Undo Log 中记录了数据的历史版本。通过 roll_pointer,InnoDB 可以在发生并发时,允许其他事务读取数据的旧版本。

六、MVCC 的实际应用场景

1. 电商系统的订单查询

在电商系统中,用户在事务 A 中查询订单时,订单数据可能会被其他事务修改或插入新记录。通过 MVCC,事务 A 查询时看到的订单数据是一致的,即便其他事务插入了新的订单,事务 A 依然能看到一个稳定的订单视图。

2. 金融系统的账户余额查询

在金融系统中,用户账户余额的查询需要确保每次查询得到的结果一致,即使账户余额在后台因某些事务而发生变化,用户也能看到一贯的账户信息,保证用户体验的一致性。MVCC 在这种场景下能保证高并发下的数据一致性。

七、总结

  • MVCC 是 InnoDB 实现高并发事务处理的重要机制,通过维护多版本数据和不加锁的快照读,解决了传统数据库加锁所带来的并发性能问题。
  • MVCC 结合事务的隔离级别,保证数据的 一致性隔离性,使得 MySQL 在高并发场景下依然能保持较高的性能。
  • 通过事务 ID、Undo Log、一致性视图等机制,InnoDB 能够高效地管理事务间的数据访问,从而避免常见的并发读写问题,例如 幻读不可重复读 等。

标签:事务,快照,MySQL,弄懂,InnoDB,版本,MVCC,数据
From: https://www.cnblogs.com/lgx211/p/18486931

相关文章

  • mysql8.0安装和配置教程
    1.下载地址:https://dev.mysql.com/downloads/mysql/进入界面是最新的版本,这里下载。1.安装MySQL2.下载3.选择自定义安装4.安装结束5.配置mysql环境变量我使用系统Windows11安装mysql选择自定义安装路径是:D:\ProgramFiles\MySQLServer8.0右键......
  • MySQL数据库备份与恢复
    MySQL数据库的备份与恢复是数据库管理的重要部分,它可以帮助我们保护数据不受硬件故障、数据损坏、人为错误等因素的影响。以下是MySQL数据备份与恢复的详细步骤和代码示例。数据备份1.使用 mysqldump 工具mysqldump是MySQL自带的一个强大的命令行工具,用于导出数据库......
  • 使用MySQL之用通配符进行过滤
    1.LIKE操作符通配符(wildcard):用来匹配值的一部分的特殊字符。搜索模式(searchpattern):由字面值、通配符或两者组合构成的搜索条件。通配符本身实际是SQL的WHERE子句中有特殊含义的字符,SQL支持几种通配符。为在搜索子句中使用通配符,必须使用LIKE操作符。LIKE指示MySQL后跟的......
  • MySQL数据库中存储图片和读取图片的操作
    文章目录方法一:将图片以BLOB类型存储在数据库中MySQL语句实现Python实现方法二:将图片存储在文件系统中,并在数据库中存储路径MySQL语句实现Python实现总结在MySQL数据库中存储图片通常有两种主要方式:将图片以二进制数据(BLOB类型)直接存储在数据库中,或者将图......
  • 科普文:软件架构数据库系列之【MySQL死锁案例分析:间隙锁“Gap Lock”导致的死锁及解决
    概叙科普文:软件架构数据库系列之【详解MySQL死锁】-CSDN博客科普文:软件架构数据库系列之【MySQL死锁案例分析:index_merge导致的死锁及解决方案ERROR1213(40001):Deadlock】-CSDN博客科普文:软件架构数据库系列之【MySQL死锁案例分析:加锁顺序“循环等待”导致的死锁及解......
  • 2024/10/19日 日志--》关于MySQL中 JDBC的API 详解的整理简述
    今天进一步学习了JDBC中的API,已经可以初步连接数据库了,接下来继续进行学习。点击查看代码--JDBCAPI详解--DirverManager--DriverManager(驱动管理类)作用:1.注册驱动2.获取数据库连接--1.注册驱动--Class.forName("com.mysql.jdbc.Driver");--·需要注意的是:My......
  • 一文搞懂MySQL索引
    索引概述介绍索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。优缺点优势劣势提高数据检索的效......
  • Mysql高级-day04
    Mysql高级-day041.MySql中常用工具1.1mysql该mysql不是指mysql服务,而是指mysql的客户端工具。语法:mysql[options][database]1.1.1连接选项参数: -u,--user=name 指定用户名 -p,--password[=name] 指定密码 -h,--host=name 指定服务器IP或域名 -P,--por......
  • Mysql高级-day02
    Mysql高级-day021.Mysql的体系结构概览整个MySQLServer由以下组成ConnectionPool:连接池组件ManagementServices&Utilities:管理服务和工具组件SQLInterface:SQL接口组件Parser:查询分析器组件Optimizer:优化器组件Caches&Buffers:缓冲池组件Plug......
  • Mysql高级-day03
    Mysql高级-day031.应用优化前面章节,我们介绍了很多数据库的优化措施。但是在实际生产环境中,由于数据库本身的性能局限,就必须要对前台的应用进行一些优化,来降低数据库的访问压力。1.1使用连接池对于访问数据库来说,建立连接的代价是比较昂贵的,因为我们频繁的创建关闭连接,是比......