高性能 MySQL(四):多版本并发控制(MVCC)

❤️个人主页:水滴V2
🚀支持水滴:点赞👍、收藏⭐、留言💬

大家好,我是水滴~~

在上一篇《高性能 MySQL(三):事务与锁详解》中,我们讲到了事务有四个标准的隔离级别,在可重复读级别中有一个幻读问题,InnoDB 是通过 MVCC 解决该问题的。

本篇就来介绍一下 MVCC 到底是什么,以及它如何解决幻读的。

1 什么是 MVCC

MVCC(Multiversion Concurrency Control)即多版本并发控制,它是数据库系统常用的一种并发控制,用于提升事务内数据的并发性。可以认为 MVCC 是行锁的一个变种,在很多种情况下避免了加锁操作,因此开销更低。

MVCC 的实现,是通过保存数据在某个时间点的快照来实现的。也就是说,每个事务读到的数据都是一个历史快照,不管这个事务执行多长时间,事务内看到的数据总是一致的。

2 InnoDB 中的 MVCC

大多数的数据库系统已经使用了 MVCC ,包括 MySQL、Oracle、PostgreSQL、HBase等等。MVCC 没有一个统一的实现标准,所以各自实现的机制不尽相同。下面我们通过 InnoDB 的简化版行为来说明 MVCC 是如何工作的。

InnoDB 实现的 MVCC,是通过在每行记录后面保存两个隐藏列来实现的。这两列,一个存储创建时的版本号,另一个存储删除时的版本号(可能为空)。这里的版本号,指的是系统版本号(System Version Number)。InnoDB 会维护一个自增的系统版本号,每开始一个新的事务时,系统版本号都会自动递增,事务开始时的系统版本号会做为事务版本号

下面特准使用一个示例,看下 MVCC 在可重复读隔离级别下是如何操作的。其中创建时的版本号使用create_version字段表示,删除时的版本号使用delete_version字段表示。

在这里插入图片描述

2.1 插入(INSERT)

为新插入的每一行保存当前事务版本号,作为行版本号(即创建时版本号)。

示例插入两条记录:

insert into `user` (id, name, balance) values (1, '刘一', 50), (2, '陈二', 100);

假设当前事务版本号为1,那么插入后的数据行如下:
在这里插入图片描述

2.2 修改(UPDATE)

更新时并不会删除旧的行,而是将旧行的删除版本号标记为当前事务版本号,再插入一行新的记录。

示例修改一条记录:

update `user` set balance = 60 where id = 1;

假设当前事务版本号为2,那么修改后的数据行如下:
在这里插入图片描述

2.3 删除(DELETE)

删除时,会将当前事务版本号作为删除版本号。

示例删除一条记录:

delete from `user` where id = 1;

假设当前事务版本号为3,那么删除后的数据行如下:
在这里插入图片描述

2.4 查询(SELECT)

查询时,有两个必要条件:

  1. 只查找,行的创建版本号小于或等于当前事务版本号的记录。这样可以确保事务读取的行,要么是事务开始前已经存在,要么是事务自身插入或修改过的。
  2. 并且,行的删除版本号要么未定义,要么大于当前事务版本号。这可以确保事务读取的行,在事务开始之前未被删除。

以上两个条件同时符合的记录,才会被查出。这也是 MVCC 不会出现幻行的原因。

3 总结

使用这两个隐藏列,使大 多数读操作都可以不用加锁,可以认为它是乐观锁的一种实现。使用这样的设计能够提高性能,并能解决幻行问题。不足之处是,每行记录都需要额外的存储空间,并且需要做更多的行检查工作,以及一些额外的维护工作。

当然这只是一个简化版的说明,真实的 MVCC 会更加复杂一些,感兴趣的老铁可以看下官网介绍:InnoDB Multi-Versioning。博主打算后面再开一个专栏,用于探索 MySQL 官网文档,毕竟那里才是最准确的一手资料!

在这里插入图片描述

  • 13
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 20
    评论
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水滴技术

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值