什么是MVCC | 数据库

冰岩作坊 October 14, 2022

什么是MVCC

全称Multi-Version Concurrency Control,即多版本并发控制,主要是为了提高数据库的并发性能。

同一行数据平时发生读写请求时,会上锁阻塞住。但mvcc用更好的方式去处理读—写请求,做到在发生读(指快照读)—写请求冲突时不用加锁。

当前读、快照读

当前读

每次读取数据库记录,都是当前最新的版本,会对当前读取的数据进行加锁,防止其他事务修改数据,是悲观锁。

如下操作都是当前读:

快照读

快照读的实现是基于多版本并发控制,即MVCC(快照读读到的数据不一定是当前最新的数据,有可能是之前历史版本的数据)

数据库并发场景

MVCC解决的问题

MVCC的实现原理

mvcc用来解决读—写冲突的无锁并发控制,为事务分配单向增长的时间戳,为每个数据修改保存一个版本,版本与事务时间戳相关联。它的实现原理主要是版本链,undo日志 ,Read View来实现的

版本链

数据库中的每行数据有几个隐藏字段,分别是db_trx_id、db_roll_pointer、db_row_id。

6byte,最近修改(修改/插入)事务ID:记录创建这条记录/最后一次修改该记录的事务ID。

7byte,回滚指针,指向这条记录的上一个版本,配合undo日志

6byte,隐含的自增ID(隐藏主键),如果数据表没有主键,InnoDB会自动以db_row_id产生一个聚簇索引。

记录被更新或删除并不代表真的删除,而是删除flag变了

undo日志

Undo log 主要用于记录数据被修改之前的日志,在表信息修改之前先会把数据拷贝到undo log里。

当事务进行回滚时可以通过undo log 里的日志进行数据还原。每次对数据库记录进行改动,都会记录一条undo日志,每条undo日志都有一个roll_pointer属性.

Undo log 的用途

代表事务在insert新记录时产生的undo log , 只在事务回滚时需要,并且在事务提交后可以被立即丢弃

事务在进行update或delete时产生的undo log ; 不仅在事务回滚时需要,在快照读时也需要;

Read View(读视图)

事务进行快照读操作的时候会产生一个读视图(Read View)。

记录并维护系统当前活跃事务的ID(没有commit),是系统中当前不应该被本事务看到的其他事务id列表。

Read View主要是用来做可见性判断的, 即当某个事务执行快照读的时候,会创建一个Read View读视图,把它比作条件用来判断当前事务能够看到哪个版本的数据,既可能是当前最新的数据,也有可能是该行记录的undo log里面的某个版本的数据。

Read View几个属性

Read View可见性判断条件

数据事务ID小于read view中的最小活跃事务ID:该数据在当前事务启之前就已经存在,可以显示。

数据的事务ID等于creator_trx_id :数据是当前事务自己生成的

数据事务ID大于read view 中的当前系统的最大事务ID:数据是在当前read view 创建之后才产生的,数据不显示。

MVCC和事务隔离级别

上面所讲的Read View用于支持RC(Read Committed,读提交)和RR(Repeatable Read,可重复读)隔离级别的实现。

RR、RC生成时机

解决幻读问题