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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: MVCC(Multiversion Concurrency Control)即多版本并发控制,它是数据库系统常用的一种并发控制,用于提升事务内数据的并发性。可以认为 MVCC 是行锁的一个变种,在很多种情况下避免了加锁操作,因此开销更低。MVCC 的实现,是通过保存数据在某个时间点的**快照**来实现的。也就是说,每个事务读到的数据都是一个历史快照,不管这个事务执行多长时间,事务内看到的数据总是一致的。

大家好,我是水滴~~

在上一篇《高性能 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字段表示。

3c4abdb5ff25da440377c046a0a28503_MVCC%20(7)_auth_key=1686635936-aRmBsNY57zUVWHQxyfM29p-0-582530d3a8c3caae240b09c154f1d5e4&file_size=10024.jpg

2.1 插入(INSERT)

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

示例插入两条记录:

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

假设当前事务版本号为1,那么插入后的数据行如下:

23997a38570bd7bf2f9fccadc2702d8a_MVCC_INSERT%20(1)_auth_key=1686635959-m4TtPUWNDKiQQ6Qsb9vDLA-0-37bbb3f7b7620fa475b39ec3918b22af&file_size=10682.jpg

2.2 修改(UPDATE)

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

示例修改一条记录:

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

假设当前事务版本号为2,那么修改后的数据行如下:

354d70df25bb98febc0e2cf4f7f6c470_MVCC_UPDATE%20(2)_auth_key=1686636022-52a7WHJvqUX4yavx3B9XNo-0-e9e24d4cb2f6279ad214ff5526ff43d4&file_size=13486.jpg

2.3 删除(DELETE)

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

示例删除一条记录:

delete from `user` where id = 1;

假设当前事务版本号为3,那么删除后的数据行如下:

f9cf3fb65d16e0b0bb660eb4b2285449_MVCC_DELETE_auth_key=1686636041-w2RpzdJeZVNt8SfZvBxDse-0-aacb0a60701353fca2e9698ec2ab8e5c&file_size=13681.jpg

2.4 查询(SELECT)

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

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

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

3 总结

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

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

6270191d2ea47a8a9327c75ab6db55eb_%E4%B8%89%E8%BF%9E_auth_key=1686636053-ehibSUCECGZFNSeLpJA6zV-0-0136d3ab1cb760abf58cfef994bd22b1&file_size=313722.jpg

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
3月前
|
存储 SQL 关系型数据库
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
|
6月前
|
消息中间件 缓存 弹性计算
纯PHP+MySQL手搓高性能论坛系统!代码精简,拒绝臃肿
本内容分享了一套经实战验证的社交系统架构设计,支撑从1到100万用户的发展,并历经6次流量洪峰考验。架构涵盖客户端层(App、小程序、公众号)、接入层(API网关、负载均衡、CDN)、业务服务层(用户、内容、关系、消息等服务)、数据层(MySQL、Redis、MongoDB等)及运维监控层(日志、监控、告警)。核心设计包括数据库分库分表、多级缓存体系、消息队列削峰填谷、CQRS模式与热点数据动态缓存。同时提供应对流量洪峰的弹性伸缩方案及降级熔断机制,并通过Prometheus实现全链路监控。开源建议结构清晰,适合大型社交平台构建与优化。
230 11
|
5月前
|
存储 关系型数据库 MySQL
【免费动手教程上线】阿里云RDS MySQL推出大容量高性能存储:高性能本地盘(最高16TB存储空间)、高性能云盘(最高64TB存储空间)
阿里云RDS MySQL提供高性能本地盘与高性能云盘等存储方案,满足用户大容量、低延迟需求。高性能本地盘单盘最大16TB,IO延时微秒级;高性能云盘兼容ESSD特性,支持IO性能突发、BPE及16K原子写等能力。此外,阿里云还提供免费动手体验教程,帮助用户直观感受云数据库 RDS 存储性能表现。
|
10月前
|
SQL 安全 关系型数据库
【MySQL基础篇】事务(事务操作、事务四大特性、并发事务问题、事务隔离级别)
事务是MySQL中一组不可分割的操作集合,确保所有操作要么全部成功,要么全部失败。本文利用SQL演示并总结了事务操作、事务四大特性、并发事务问题、事务隔离级别。
4234 56
【MySQL基础篇】事务(事务操作、事务四大特性、并发事务问题、事务隔离级别)
|
8月前
|
SQL 关系型数据库 MySQL
京东面试:MySQL MVCC是如何实现的?如何通过MVCC实现读已提交、可重复读隔离级别的?
1.请解释什么是MVCC,它在数据库中的作用是什么? 2.在MySQL中,MVCC是如何实现的?请简述其工作原理。 3.MVCC是如何解决读-写和写-写冲突的? 4.在并发环境中,当多个事务同时读取同一行数据时,MVCC是如何保证每个事务看到的数据版本是一致的? 5.MVCC如何帮助提高数据库的并发性能?
京东面试:MySQL MVCC是如何实现的?如何通过MVCC实现读已提交、可重复读隔离级别的?
|
9月前
|
SQL 关系型数据库 MySQL
vb6读取mysql,用odbc mysql 5.3版本驱动
通过以上步骤,您可以在VB6中使用ODBC MySQL 5.3驱动连接MySQL数据库并读取数据。配置ODBC数据源、编写VB6代码
225 32
|
10月前
|
关系型数据库 MySQL Linux
MySQL版本升级(8.0.31->8.0.37)
本次升级将MySQL从8.0.31升级到8.0.37,采用就地升级方式。具体步骤包括:停止MySQL服务、备份数据目录、下载并解压新版本的RPM包,使用`yum update`命令更新已安装的MySQL组件,最后启动MySQL服务并验证版本。整个过程需确保所有相关RPM包一同升级,避免部分包遗漏导致的问题。官方文档提供了详细指导,确保升级顺利进行。
996 16
|
9月前
|
SQL 存储 关系型数据库
MySQL进阶突击系列(05)突击MVCC核心原理 | 左右护法ReadView视图和undoLog版本链强强联合
2024年小结:感谢阿里云开发者社区每月的分享交流活动,支持持续学习和进步。过去五个月投稿29篇,其中17篇获高分认可。本文详细介绍了MySQL InnoDB存储引擎的MVCC机制,包括数据版本链、readView视图及解决脏读、不可重复读、幻读问题的demo演示。
|
10月前
|
SQL 存储 关系型数据库
Mysql并发控制和日志
通过深入理解和应用 MySQL 的并发控制和日志管理技术,您可以显著提升数据库系统的效率和稳定性。
351 10

推荐镜像

更多