MySQL-MVCC举例说明

在数据库系统中,多版本并发控制(MVCC, Multi-Version Concurrency Control) 是一种用于提高并发性能的机制,它允许多个事务同时读取和写入数据,而不会产生锁等待和阻塞的问题。MySQL 的 InnoDB 存储引擎广泛使用了 MVCC 来处理并发事务。为了深入理解 MVCC 的工作原理,我们需要了解事务、版本链、Read View 的概念。

1. 事务和版本链

1.1 事务的基本概念
  • 事务(Transaction) 是数据库中的一个操作序列,这些操作要么全部执行成功,要么全部撤销。事务具有四个特性:原子性、一致性、隔离性、持久性(ACID)。
  • 在 MVCC 中,每个事务都有一个唯一的事务 ID(trx_id),用于标识事务。
1.2 版本链
  • 在 InnoDB 中,每一行数据都有一个隐藏的列 trx_id,记录了最后一次修改该行的事务 ID。
  • 当一条记录被更新时,InnoDB 并不会立即删除旧的记录,而是将新的记录作为一个版本(新版本)插入,并将旧记录保留作为历史版本。
  • 这些历史版本通过指针链接起来,形成一个版本链。最新的记录在链的头部,旧版本依次排在后面。

2. Read View 和 MVCC

在 MVCC 中,事务在读取数据时会创建一个 Read View。Read View 记录了当前数据库中活跃事务的状态,并通过它来决定哪些数据版本对当前事务可见,哪些不可见。

2.1 Read View 的关键属性

在创建 Read View 后,我们可以将记录中的 trx id 划分这三种情况:

  • min_trx_id :当前系统中所有未提交事务的最小事务 ID。表示在 Read View 创建时,所有事务 ID 小于 min_trx_id 的事务都已经提交。
  • max_trx_id :在 Read View 创建时数据库中下一个将要分配的事务 ID。表示在 Read View 创建时,所有事务 ID 大于等于 max_trx_id 的事务是未来才会启动的事务。
  • m_ids:在 Read View 创建时,当前系统中所有活跃的事务 ID 列表。表示在 Read View 创建时,这些事务还未提交。
2.2 MVCC 的可见性规则

当一个事务试图读取某条记录时,InnoDB 会使用 MVCC 机制判断该记录的哪个版本对当前事务可见。判断过程如下:

  1. 自己的事务更新的记录总是可见

    • 如果当前事务对某条记录进行了更新(创建了新版本),那么这个版本对该事务总是可见的。
  2. 记录的 trx_id 小于 min_trx_id

    • 如果记录的 trx_id 小于 min_trx_id,说明这个版本的记录是在创建 Read View 之前的某个事务中生成的,且该事务已经提交。
    • 因此,这个版本的记录对当前事务是可见的。
  3. 记录的 trx_id 大于等于 max_trx_id

    • 如果记录的 trx_id 大于等于 max_trx_id,说明这个版本的记录是在创建 Read View 之后的某个事务中生成的(这些事务甚至可能还未开始)。
    • 因此,这个版本的记录对当前事务不可见。
  4. 记录的 trx_idmin_trx_idmax_trx_id 之间

    • 如果记录的 trx_id 介于 min_trx_idmax_trx_id 之间,需要进一步检查 trx_id 是否在 m_ids 列表中:
      • m_ids 列表中:表示生成该版本的事务还没有提交,仍然是活跃的。这时,该版本对当前事务不可见,因为它还处于未提交状态。
      • 不在 m_ids 列表中:表示生成该版本的事务已经提交,所以这个版本对当前事务可见。

3. 举例说明

假设当前有三个事务:

  • 事务 A(trx_id = 10):已提交。
  • 事务 B(trx_id = 15):未提交,仍在进行中。
  • 事务 C(trx_id = 20):未提交,仍在进行中。

假设当前有一个事务 D 正在运行,它的 trx_id 是 25。事务 D 创建了一个 Read View,假设在创建时系统的下一个事务 ID 为 30。

此时 Read View 的属性值为:

  • min_trx_id = 15(未提交的事务中最小的 ID)。
  • max_trx_id = 30(下一个将要分配的事务 ID)。
  • m_ids = [15, 20](未提交的事务列表)。

现在,事务 D 要读取某条记录,假设该记录的不同版本的 trx_id 分别是 10(旧版本)和 20(新版本),我们来看哪些版本对事务 D 可见:

  • 版本 1(trx_id = 10)
    • 10 < min_trx_id,这个版本的记录是在事务 D 的 Read View 创建之前已经提交的,因此对事务 D 可见。
  • 版本 2(trx_id = 20)
    • 20 在 min_trx_idmax_trx_id 之间,而且 20 在 m_ids 列表中,这意味着这个版本是由仍然活跃的事务 C 创建的,且未提交。
    • 因此,这个版本的记录对事务 D 不可见。

4. MVCC 的优点

  • 高并发性能:MVCC 允许读写操作并发进行,读操作不会阻塞写操作,写操作也不会阻塞读操作。
  • 一致性读取:通过 Read View,MVCC 确保每个事务读取到的都是一致的数据快照,而不会受到其他事务未提交修改的影响。
  • 无锁读:MVCC 实现了大多数情况下的无锁读操作,提高了数据库的整体性能。

5. MVCC 的局限性

  • 空间开销:由于需要保留旧版本数据,因此 MVCC 会增加数据存储的空间开销。
  • 垃圾数据清理:随着数据的不断更新和删除,版本链会变长,MySQL 需要定期清理不再需要的旧版本数据,这通常由后台线程完成。

6. 总结

MVCC 是 MySQL InnoDB 存储引擎用来处理并发事务的一种重要机制。通过版本链和 Read View 的机制,MVCC 能够高效地处理多个事务的并发读写操作,确保数据的一致性和系统的高性能。了解 MVCC 的工作原理,对于优化 MySQL 性能和解决并发问题至关重要。

相关推荐
Acrelhuang18 分钟前
安科瑞5G基站直流叠光监控系统-安科瑞黄安南
大数据·数据库·数据仓库·物联网
十叶知秋1 小时前
【jmeter】jmeter的线程组功能的详细介绍
数据库·jmeter·性能测试
瓜牛_gn3 小时前
mysql特性
数据库·mysql
奶糖趣多多4 小时前
Redis知识点
数据库·redis·缓存
CoderIsArt5 小时前
Redis的三种模式:主从模式,哨兵与集群模式
数据库·redis·缓存
师太,答应老衲吧7 小时前
SQL实战训练之,力扣:2020. 无流量的帐户数(递归)
数据库·sql·leetcode
Yaml48 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
Channing Lewis8 小时前
salesforce case可以新建一个roll up 字段,统计出这个case下的email数量吗
数据库·salesforce
追风林8 小时前
mac 本地docker-mysql主从复制部署
mysql·macos·docker
毕业设计制作和分享9 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis