20张图,全面掌握MVCC原理!

前言

大家好,今天分享一篇fancy大佬对MVCC的深度剖析。

在前面关于MySQL的文章中,我们讲到了事务的特性、隔离级别和并发一致性问题。其中我们说到了数据库的四个隔离级别,并说明MVCC是实现了提交读,可重复读的重要手段。

MVCC也是MySQL数据库中一个老生常谈的话题了,但是由于它较为底层,实际的开发日常中我们并不会去直接接触它,所以真正将它弄明白的人并不多,许多面试者,提到它很多人都处于:“哦,这个东西我知道!是数据库中的一种并发措施,但是我有点忘记了它的详细内容了...”这样的状态。

所以本篇文章,就来详细讲一讲”MVCC”,带大家理清楚MVCC的内容。

话不多说,列大纲,发车!

什么是MVCC?

MVCC((Mutil-Version Concurrency Control)),全称多版本并发访问,这是一种并发环境下进行数据安全控制的方法,其本质上是一种乐观锁,用于实现提交读(READ COMMITTD)和可重复读(REPEATABLE READ)这两种隔离级别。在这里我先为大家理清楚一个概念:我们常说的MVCC是由MySQL数据库InnoDB存储引擎实现的,并非是由MySQL本身实现的,不同的存储引擎,对MVCC都有不同的实现标准。所以当你在面试官面前说:”MySQL使用了MVCC实现了xxxxxx“,面试官一下子就把你给逮住了,说明你连MySQL和InnoDB之间的关系都模糊不清😑。

那么,当你听到了“多版本”、“并发访问”这两个词,你也许就知道了,InnoDB使用MVCC来解决并发问题的方法,就是让每个不同的事务访问查询同一行数据时,每个事务修改的都是这行数据的不同版本,InnoDB只需要去记录这个数据的访问链,就可以实现一个SELECT操作的并发执行。

那么,它具体是如何实现的呢?

MVCC利用了多版本的思想,在 MVCC 中事务的所有写操作(INSERT、UPDATE、DELETE)会为数据行新增一个最新的版本快照,而读操作是去读旧版本的快照,也就是说,读操作和写操作是分离的,二者之间没有依赖、互斥关系。

核心

Undo Log

什么是Undo Log?

Undo Log是MySQL的三大日志之一,当我们对记录做了变更操作时就会产生一条Undo记录。它的作用就是保护事务在异常发生的时候或手动回滚时可以回滚到历史版本数据,能够让你读取过去某一个时间点保存的数据。通俗易懂地说,它只关心过去的数据。

本文我们不会对Undo Log的作用做太多描述,你需要重点知道的是:对于一个InnoDB存储引擎,一个聚簇索引(主键索引)的记录之中,一定会有两个隐藏

### 多版本并发控制 (MVCC) 原理解释 #### 数据库中的事务隔离级别与MVCC的关系 为了确保数据库系统的高并发性和数据一致性,多版本并发控制(MVCC)通过为每个事务提供一个特定时间点的数据快照来工作。这意味着当一个新的事务启动时,它会基于其开始的时间点获得一份当前所有记录的状态副本[^3]。 #### MVCC的核心概念 - **隐藏列**:在支持MVCC的存储引擎中,每条记录都隐含着两个额外字段——创建时间和删除时间戳。这些时间戳不是实际的日志时间而是逻辑上的序列号,代表某个事务ID。 - **非锁定读取**:对于大多数查询而言,默认情况下它们是非锁定性质的操作;也就是说,除非显式指定了独占锁或其他类型的锁定语句外,普通的`SELECT`命令不会阻止其他进程对该表项进行更新或插入新行[^1]。 - **可见性规则**:决定哪些版本应该被呈现给正在运行中的各个事务。具体来说,如果一条记录是在某次事务之前生成并提交过的,则这条记录对这个事务是可见的;反之则不可见。这种机制有效地防止了脏读、幻影读等问题的发生[^2]。 #### 实现细节 以InnoDB为例说明其实现方式: - 当执行DML操作如INSERT, UPDATE 或 DELETE 时,除了改变现有元组之外还会标记旧版本的有效期以及新增加的新版本的信息; - 对于每一个新的写入动作都会分配唯一的递增事务编号作为标识符,并将其关联至相应的变更上; - 查询过程中利用上述提到的时间戳来进行过滤判断,从而返回最合适的那套历史数据集给请求方。 ```sql -- 插入新纪录的同时设置create_ts和delete_ts初始值 INSERT INTO table_name (data_column, create_ts, delete_ts) VALUES ('example', CURRENT_TIMESTAMP(), NULL); -- 更新已有记录时复制原版并更改状态标志位 UPDATE table_name SET data_column='new_value', old_version=create_ts, new_version=CURRENT_TIMESTAMP(), deleted=TRUE WHERE id = specific_id; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值