MySQL中的MVCC机制
已于 2023-02-13 11:54:03 修改·357 阅读
1
1·
MVCC(多版本并发控制)是提高数据库并发性能的技术,它避免了读写冲突时的加锁操作。MySQL InnoDB的MVCC分为当前读(加锁操作)和快照读(基于MVCC)。MVCC依赖于记录中的隐藏字段、undo log和Read View来实现。undo log用于记录数据的历史版本,Read View是快照读的依据,它记录活跃事务ID,用于判断数据的可见性。在RC(读已提交)和RR(可重复读)隔离级别下,Read View的生成时机不同,影响了快照读的结果。RR级别的MVCC可以避免幻读,而RC级别则可能出现幻读。1. 什么是MVCC
MVCC全称Multi-Version Concurrency Control,即多版本并发控制,主要是为了提高数据库的并发性能。同一行数据平时发生读写请求时,会上锁阻塞住。但mvcc用更好的方式去处理读写请求,做到在发生读写请求冲突时不用加锁。
这个读指的是快照读,而不是当前读,当前读是一种加锁操作,是悲观锁。
2. 什么是MySQL InnoDB下的当前读和快照读
当前读:针对写操作(先进行数据查询,再进行数据更改)所产生的读被称为当前读,当前读读取的数据库记录都是当前最新的版本,会对当前读取的数据进行加锁(主要是采用行锁和间隙锁),防止其它事务修改数据,是悲观锁的一种操作。
如下操作都是当前读:
select ...... lock in share mode(共享锁)
select ...... for update(排它锁)
update(排它锁)
insert(排它锁)
delete(排它锁)
快照读:快照读的实现是基于多版本并发控制,即MVCC,既然是多版本,那么快照读读到的数据不一定是当前最新的数据,有可能是之前历史版本的数据。
如下操作是快照读:
不加锁的select操作(注:事务级别不是串行化)
3. MVCC里面的相关概念
mvcc的实现原理主要依赖于记录中的三个隐藏字段、undo log、readview来实现
3.1 三个隐藏字段
每行记录除了我们自定义的字段外,还有数据库隐式定义的DB_TRX_ID、DB_ROLL_PTR、DB_ROW_ID等三个字段。
DB_TRX_ID:最近修改事务ID(6字节),记录创建这条记录或者最后一次修改该记录的事务ID
DB_ROLL_PTR:回滚指针(7字节),指向这条记录的上一个版本,用于配合undolog,指向上一个旧版本
DB_ROW_ID:隐藏的主键(6字节),如果数据表没有主键,那么innodb会自动生成一个6字节的row_id
数据行记录如图所示:

在上图中,DB_ROW_ID是数据库默认为该行记录生成的唯一隐式主键, DB_TRX_ID是当前操作该记录的事务ID,DB_ROLL_PTR是一个回滚指针,用于配合undo日志,指向上一个旧版本。
3.2 undo log
undo log被称之为回滚日志,表示在进行insert、delete、update操作的时候产生的方便回滚的日志。
当进行insert操作的时候,产生的undo log只在事务回滚的时候需要,并且在事务提交之后可以被立刻丢弃。
当进行update和delete操作的时候,产生的undo log不仅仅在事务回滚的时候需要,在快照读的时候也需要,所以不能随便删除,只有在快照读或者事务回滚不涉及该日志时,对应的日志才会被purge线程统一清除。
下面我们来看一下undo log生成的记录链
1、假设有一个事务编号为1的事务向表中插入一条记录,那么此时行数据的状态如下所示:

2233
1464
最低0.47元/天 解锁文章















































































