一文读懂 Mysql MVCC

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: MVCC(Multi-Version Concurrency Control)是一种**多版本并发控制**技术,常用于数据库管理系统中,用于支持事务的并发执行。MVCC 技术可以在读取数据时不产生锁,同时保证数据的一致性。具体来说,MVCC 技术会在每个数据行上保存多个版本的数据,每个版本都有一个时间戳,当一个事务需要读取数据时,会根据该事务的时间戳选择合适的数据版本进行读取,从而避免了读取数据时的锁定操作。同时,MVCC 技术还可以通过回滚日志和垃圾回收机制来保证数据的一致性和完整性。MVCC 技术在 InnoDB 存储引擎中得到了广泛的应用,成为了 InnoDB 存储引擎的一个重要特性

博主介绍: ✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家✌

Java知识图谱点击链接:体系化学习Java(Java面试专题)

💕💕 感兴趣的同学可以收藏关注下不然下次找不到哟💕💕

1686575276531.jpg

1、什么是 MVCC

MVCC(Multi-Version Concurrency Control)是一种多版本并发控制技术,常用于数据库管理系统中,用于支持事务的并发执行。MVCC 技术可以在读取数据时不产生锁,同时保证数据的一致性。具体来说,MVCC 技术会在每个数据行上保存多个版本的数据,每个版本都有一个时间戳,当一个事务需要读取数据时,会根据该事务的时间戳选择合适的数据版本进行读取,从而避免了读取数据时的锁定操作。同时,MVCC 技术还可以通过回滚日志和垃圾回收机制来保证数据的一致性和完整性。MVCC 技术在 InnoDB 存储引擎中得到了广泛的应用,成为了 InnoDB 存储引擎的一个重要特性。

正是因为有了 MVCC,所以 Mysql 的并发性能才会更好。

2、什么是当前读、快照读

当前读和快照读是 InnoDB 存储引擎中的两种读取数据的方式。

当前读:是指在读取数据时,使用的是最新的数据版本。当前读可以通过 SELECT ... FOR UPDATE (排它锁)或者 SELECT ... LOCK IN SHARE MODE (共享锁)等语句实现。在当前读的情况下,如果其他事务正在修改该数据行,当前读会被阻塞,直到其他事务释放锁。

快照读:是指在读取数据时,使用的是指定时间点的数据版本。快照读可以通过 SELECT ... FROM ... AS OF 或者 SELECT ... FROM ... VERSIONS BETWEEN ... AND ... 等语句实现。在快照读的情况下,如果其他事务正在修改该数据行,快照读不会被阻塞,而是读取该数据行的历史版本。快照读可以提高并发读取数据的效率,但是可能会读取到已经被修改的数据行。

SELECT ... FROM ... AS OF 是一种快照读取数据的方式。它可以在读取数据时指定一个时间点,然后读取该时间点的数据版本,而不是当前的数据版本。这种方式不会对其他事务产生锁定,因此可以提高并发性能。在使用 AS OF 语句时,InnoDB 存储引擎会从回滚日志中读取指定时间点的数据版本,并返回给用户。需要注意的是,使用 AS OF 语句时,需要保证指定的时间点在当前事务开始之前,否则可能会读取到未提交的数据,导致数据不一致。

SELECT ... FROM ... VERSIONS BETWEEN ... AND ... 是一种快照读取数据的方式,可以读取指定时间范围内的数据版本。在使用该语句时,需要指定开始时间和结束时间,然后 InnoDB 存储引擎会读取这个时间范围内的所有数据版本,并将它们返回给用户。这种方式不会对其他事务产生锁定,因此可以提高并发性能。需要注意的是,使用 VERSIONS BETWEEN 语句时,需要保证指定的时间范围在当前事务开始之前,否则可能会读取到未提交的数据,导致数据不一致。

当前读适合于需要修改数据的场景,而快照读适合于只需要读取数据的场景。

3、MVCC 具体解决什么问题

首先说下数据库的并发场景可以分为以下几种:

  1. 读写并发:多个事务同时对同一数据进行读和写操作。这种场景需要使用并发控制机制来保证数据的一致性和完整性。

  2. 写写并发:多个事务同时对同一数据进行写操作。这种场景需要使用锁定机制来保证数据的一致性和完整性。

  3. 读读并发:多个事务同时对同一数据进行读操作。这种场景不需要使用并发控制机制,可以提高数据库系统的并发性能。

  4. 隔离级别并发:不同事务之间的隔离级别不同,可能会导致数据不一致的问题。这种场景需要使用事务隔离级别机制来保证数据的一致性和完整性。

  5. 死锁并发:多个事务之间相互依赖,可能会出现死锁的情况。这种场景需要使用死锁检测和解决机制来避免死锁的发生。

而 MVCC 主要解决数据库系统中的并发控制问题。在多用户并发访问数据库时,如果不进行并发控制,可能会导致数据不一致的问题。传统的并发控制方式是使用锁定机制,即在读取或修改数据时,需要先对数据行进行加锁,防止其他事务同时对该数据行进行修改。这种方式虽然可以保证数据的一致性,但是会降低并发性能,因为同时只有一个事务可以对数据行进行操作。
MVCC 技术通过在每个数据行上保存多个版本的数据,每个版本都有一个时间戳,来实现并发控制。当一个事务需要读取数据时,会根据该事务的时间戳选择合适的数据版本进行读取,从而避免了读取数据时的锁定操作。同时,MVCC 技术还可以通过回滚日志和垃圾回收机制来保证数据的一致性和完整性。MVCC 技术可以提高数据库系统的并发性能,同时保证数据的一致性。

MVCC + 悲观锁:MVCC 解决读写冲突,悲观锁解决写写冲突
MVCC + 乐观锁:MVCC解决读写冲突,乐观锁解决写写冲突

4、MVCC 的实现原理

在这里插入图片描述
MVCC 的实现原理主要是在每个数据行上保存多个版本的数据,并通过版本号和时间戳来实现并发控制。具体实现步骤如下:

  1. 在每个数据行上保存多个版本的数据。每个版本都有一个唯一的版本号和时间戳,用于标识该版本的数据是在何时被修改的。

  2. 当一个事务需要读取数据时,会根据该事务的时间戳选择合适的数据版本进行读取。如果该事务的时间戳早于某个数据版本的时间戳,则该数据版本对该事务不可见,因为该数据版本是在该事务开始之后被修改的。

  3. 当一个事务需要修改数据时,会先将原始数据行复制一份,并在新复制的数据行上进行修改。同时,该事务会生成一个新的版本号和时间戳,并将新版本的数据行插入到数据库中。这样,原始数据行和新数据行就形成了一个版本链。

  4. 当一个事务提交时,会将该事务所修改的数据行的最新版本号和时间戳更新到事务提交记录中。这样,其他事务就可以根据该事务的提交记录来选择合适的数据版本进行读取。

  5. 当一个事务回滚时,会将该事务所修改的数据行的最新版本号和时间戳恢复到事务开始时的状态。这样,其他事务就可以根据该事务的回滚记录来选择合适的数据版本进行读取。

  6. 为了避免版本链过长,数据库系统会定期进行垃圾回收,删除不再需要的版本。这样可以减少数据库系统的存储空间和提高查询性能。

为了解决读写冲突主要是依赖记录中的 4个隐式字段,undo日志 ,Read View 来实现的

4.1、4个隐式字段

MVCC(多版本并发控制)是一种用于数据库系统的并发控制技术,它通过在每个数据行上保存多个版本的数据,每个版本都有一个时间戳,来实现并发控制。在 MVCC 中,每个数据行都有四个隐式字段,分别是:

  1. Transaction ID:事务 ID,表示修改该数据行的事务的 ID。
  2. Rollback Pointer:回滚指针,指向该事务的回滚日志,用于撤销该事务对该数据行的修改。
  3. Row Start:行开始时间戳,表示该数据行的版本开始时间。
  4. Row End:行结束时间戳,表示该数据行的版本结束时间。

image.png

这四个隐式字段是 MVCC 技术实现并发控制的关键,它们记录了每个数据行的修改历史和版本信息,用于支持并发事务的读写操作。当一个事务需要读取数据时,会根据该事务的时间戳选择合适的数据版本进行读取,从而避免了读取数据时的锁定操作。同时,MVCC 技术还可以通过回滚日志和垃圾回收机制来保证数据的一致性和完整性。

4.2、undo 日志

Undo 日志是数据库系统中的一种重要的日志记录机制,用于支持事务的回滚和 MVCC(多版本并发控制)技术的实现。当一个事务执行修改操作时,数据库系统会将修改前的数据记录到 Undo 日志中,以便在事务回滚时可以恢复到修改前的状态。同时,在 MVCC 技术中,Undo 日志还用于保存每个数据行的历史版本信息,以便支持并发事务的读写操作。

下面是一个使用 Undo 日志的 SQL 示例:
假设有一个表 t,其中包含两个字段 id 和 name,现在执行以下 SQL:

UPDATE t SET name = 'new_name' WHERE id = 1;

执行该 SQL 语句时,数据库系统会将 id 为 1 的数据行修改前的值记录到 Undo 日志中。如果事务回滚,则可以使用 Undo 日志将该数据行恢复到修改前的状态。

另外,如果该表使用了 MVCC 技术,在每个数据行中也会保存 Undo 日志,用于支持并发事务的读写操作。当一个事务需要读取数据时,会根据该事务的时间戳选择合适的数据版本进行读取。如果需要回滚该事务,则可以使用 Undo 日志将该数据行恢复到指定的历史版本。

4.3、Read View

Read View 是 MySQL 中用于实现 MVCC 的一种机制,用于支持并发事务的读操作。在 MySQL 中,每个事务都有自己的 Read View,用于确定该事务可以读取到哪些数据版本。Read View 由以下两个部分组成:

  1. Trx ID 列表:该列表记录了当前事务启动时,已经提交的事务 ID 列表。
  2. 快照版本号:该版本号记录了当前事务启动时,数据库系统的快照版本号。

在执行读操作时,MySQL 会将当前事务的 Read View 与数据行的版本信息进行比较,从而确定当前事务可以读取哪些数据版本。如果数据版本早于当前事务的快照版本号或者是由未提交的事务所产生的版本,则当前事务无法读取该数据版本。

以下是一个示例 SQL 语句,说明 Read View 的工作原理:

-- 事务 A
START TRANSACTION;
SELECT * FROM t WHERE id = 1;

 -- 事务 B
START TRANSACTION;
UPDATE t SET name = 'new_name' WHERE id = 1;
COMMIT;

 -- 事务 A
SELECT * FROM t WHERE id = 1;
COMMIT;

在上述示例中,事务 A 在启动时会创建自己的 Read View,并记录当前数据库系统的快照版本号。在第一个 SELECT 语句中,事务 A 会根据自己的 Read View 读取 id 为 1 的数据行,此时由于事务 B 已经对该数据行进行了修改,因此事务 A 无法读取到该数据行的旧版本。

在事务 B 中,执行 UPDATE 语句时,会创建一个新的数据行版本,并将该版本的事务 ID 记录到 redo 日志中。同时,由于该版本的事务 ID 还未提交,因此该版本不会被事务 A 的 Read View 所包含。

在事务 A 中的第二个 SELECT 语句中,由于该语句在事务 A 启动之后执行,因此会使用事务 A 的当前 Read View 进行读取。由于事务 A 的 Read View 不包含事务 B 所提交的事务 ID,因此事务 A 可以读取到 id 为 1 的数据行的旧版本。

5、使用 MVCC 时,需要注意什么问题

  1. 事务启动时间:事务的启动时间会影响到事务能够读取到哪些数据版本。如果事务启动时间早于某个数据版本的创建时间,则该事务可以读取到该数据版本。因此,需要确保事务启动时间在需要读取的数据版本之后。

  2. 版本回收:MVCC 技术需要维护多个数据版本,因此需要定期清理不再需要的版本,避免占用过多的存储空间。在 MySQL 中,使用 purge 线程来定期清理不再需要的版本。

  3. 长事务:长时间运行的事务会占用大量的 MVCC 版本,导致存储空间不足或性能下降。因此,需要避免长时间运行的事务,或者使用合适的事务隔离级别来减少 MVCC 版本的数量。

  4. 并发度:MVCC 技术可以提高数据库系统的并发性能,但是也需要考虑并发度的问题。如果并发度过高,可能会导致 MVCC 版本的数量过多,从而影响性能。

  5. 事务隔离级别:在使用 MVCC 技术时,需要根据具体的业务需求选择合适的事务隔离级别。不同的隔离级别会影响 MVCC 版本的数量和读取的数据版本,从而影响并发性能和数据一致性。需要根据具体的业务需求进行选择。

1686494501743.jpg

💕💕 本文由激流丶创作,原创不易,感谢支持!
💕💕喜欢的话记得点赞收藏啊!

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
6月前
|
关系型数据库 MySQL
|
6月前
|
Oracle 关系型数据库 MySQL
MySQL相关(六)- 事务隔离级别的实现方案(MVCC)
MySQL相关(六)- 事务隔离级别的实现方案(MVCC)
79 0
|
6月前
|
存储 缓存 关系型数据库
⑩⑧【MySQL】InnoDB架构、事务原理、MVCC多版本并发控制
⑩⑧【MySQL】InnoDB架构、事务原理、MVCC多版本并发控制
217 0
|
22天前
|
存储 关系型数据库 MySQL
MySQL MVCC全面解读:掌握并发控制的核心机制
【10月更文挑战第15天】 在数据库管理系统中,MySQL的InnoDB存储引擎采用了一种称为MVCC(Multi-Version Concurrency Control,多版本并发控制)的技术来处理事务的并发访问。MVCC不仅提高了数据库的并发性能,还保证了事务的隔离性。本文将深入探讨MySQL中的MVCC机制,为你在面试中遇到的相关问题提供全面的解答。
64 2
|
22天前
|
存储 关系型数据库 MySQL
MySQL MVCC深度解析:掌握并发控制的艺术
【10月更文挑战第23天】 在数据库领域,MVCC(Multi-Version Concurrency Control,多版本并发控制)是一种重要的并发控制机制,它允许多个事务并发执行而不产生冲突。MySQL作为广泛使用的数据库系统,其InnoDB存储引擎就采用了MVCC来处理事务。本文将深入探讨MySQL中的MVCC机制,帮助你在面试中自信应对相关问题。
70 3
|
5月前
|
存储 关系型数据库 MySQL
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
|
2月前
|
关系型数据库 MySQL 数据库
MySQL高级篇——MVCC多版本并发控制
什么是MVCC、快照读与当前读、隐藏字段、Undo Log版本链、ReadView、举例说明、InnoDB 解决幻读问题
MySQL高级篇——MVCC多版本并发控制
|
3月前
|
SQL 关系型数据库 MySQL
Mysql原理与调优-事务与MVCC
【8月更文挑战第19天】
|
4月前
|
SQL 存储 关系型数据库
(九)MySQL之MVCC机制:为什么你改了的数据我还看不见?
在《MySQL锁机制》这篇文章中,咱们全面剖析了MySQL提供的锁机制,对于并发事务通常可以通过其提供的各类锁,去确保各场景下的线程安全问题,从而能够防止脏写、脏读、不可重复读及幻读这类问题出现。
111 0
|
3月前
|
关系型数据库 MySQL 数据库
MySQL MVCC和间隙锁有什么区别?
【8月更文挑战第24天】MySQL MVCC和间隙锁有什么区别?
89 0