全网最详细MVCC讲解,一篇看懂

MVCC 是一种强大的并发控制机制,在高并发环境中起着重要的作用 。通过了解 MVCC 的原理和实现流程,我们可以更好地理解 MySQL 的并发控制机制,理解 MVCC 的原理对于接触 MySQL 的开发人员来说是必不可少的知识点 。
摘要在当今高度并发的数据库环境中,有效的并发控制是至关重要的 。MVCC是MySQL中被广泛采用的并发控制机制 , 它通过版本管理来实现事务的隔离性,允许读写操作同时进行,提高数据库的并发性能和响应能力 。
本文将深入解析MVCC机制的原理,帮助读者更好地理解和应用这一关键技术 。
MVCC 介绍MVCC , 全称 Multi-Version Concurrency Control,即多版本并发控制
MVCC的目的主要是为了提高数据库并发性能,用更好的方式去处理读-写冲突,做到即使有读写冲突时,也能做到不加锁 。
这里的多版本指的是数据库中同时存在多个版本的数据 , 并不是整个数据库的多个版本,而是某一条记录的多个版本同时存在 。
并发控制的挑战
在数据库系统中 , 同时执行的事务可能涉及相同的数据,因此需要一种机制来保证数据的一致性 , 传统的锁机制可以实现并发控制,但会导致阻塞和死锁等问题 。
MVCC的优点
MVCC机制具有以下优点:
提高并发性能:读操作不会阻塞写操作,写操作也不会阻塞读操作,有效地提高数据库的并发性能 。
降低死锁风险:由于无需使用显式锁来进行并发控制,MVCC可以降低死锁的风险 。
当前读和快照读在讲解MVCC原理之前 , 我们先来了解一下,当前读和快照读 。
当前读
在MySQL中,当前读是一种读取数据的操作方式 , 它可以直接读取最新的数据版本,读取时还要保证其他并发事务不能修改当前记录 , 会对读取的记录进行加锁 。MySQL提供了两种实现当前读的机制:

  • 一致性读(Consistent Read):
默认隔离级别下(可重复读),MySQL使用一致性读来实现当前读 。
在事务开始时,MySQL会创建一个一致性视图(Consistent View),该视图反映了事务开始时刻数据库的快照 。
在事务执行期间,无论其他事务对数据进行了何种修改,事务始终使用一致性视图来读取数据 。
这样可以保证在同一个事务内多次查询返回的结果是一致的,从而实现了当前读 。
  • 锁定读(Locking Read):
  • 锁定读是一种特殊情况下的当前读方式 , 在某些场景下使用 。
  • 当使用锁定读时,MySQL会在执行读取操作前获取共享锁或排他锁,以确保数据的一致性 。
  • 共享锁(Shared Lock)允许多个事务同时读取同一数据 , 而排他锁(Exclusive Lock)则阻止其他事务读取或写入该数据 。
  • 锁定读适用于需要严格控制并发访问的场景,但由于加锁带来的性能开销较大,建议仅在必要时使用 。
下面列举的这些语法都是当前读:
语法
SELECT ... LOCK IN SHARE MODE
SELECT ... FOR UPDATE
UPDATE
DELETE
INSERT
当前读实际上是一种加锁的操作,是悲观锁的实现 。
快照读
快照读是在读取数据时读取一个一致性视图中的数据,MySQL使用 MVCC 机制来支持快照读 。
具体而言,每个事务在开始时会创建一个一致性视图(Consistent View),该视图反映了事务开始时刻数据库的快照 。这个一致性视图会记录当前事务开始时已经提交的数据版本 。
当执行查询操作时,MySQL会根据事务的一致性视图来决定可见的数据版本 。只有那些在事务开始之前已经提交的数据版本才是可见的,未提交的数据或在事务开始后修改的数据则对当前事务不可见 。
像不加锁的 select 操作就是快照读,即不加锁的非阻塞读 。
快照读可能读到的并不一定是数据的最新版本,而有可能是之前的历史版本 。
注意:快照读的前提是隔离级别不是串行级别 , 在串行级别下 , 事务之间完全串行执行,快照读会退化为当前读
MVCC主要就是为了实现读-写冲突不加锁,而这个读指的就是快照读,是乐观锁的实现 。
MVCC 原理解析隐式字段MySQL中的行数据,除了我们肉眼能看到的字段之外,其实还包含了一些隐藏字段,它们在内部使用 , 默认情况下不会显示给用户 。


推荐阅读