MVCC的意思是多版本并发控制,是在并发访问数据库时,通过对数据进行多版本控制,从而解决锁问题
MVCC
为什么需要MVCC
从标题中也可以窥见答案:为了解决并发问题,我们思考一下如果我们需要并发编程中的读写问题
- 对并发访问的数据加一把排他锁,这样就只有一个事务可以对数据进行读或者写操作
- 对并发的访问的数据加一把读写锁,读操作不需要阻塞,而写操作需要阻塞读操作和其余写操作
- 对并发的数据进行快照备份,从而可以访问到任何版本的内容
MVCC的实现原理
MVCC实现的两个核心分别是 undo log
和一致性视图,其中 undo log
用来保存版本的数据,而一致性视图用来保存当前活跃的事物列表。
undo log
innodb
在每一次修改数据库之前都会把操作日志写在 undo log
中,undo log
文件一般存放在共享表空间中,实际上 undo log
的修改会反应在 redo log
文件中,redo log
会直接反应在磁盘中。
undo log
实现了数据库快照功能,通过事务id和 undo log
我们可以找到历史版本的数据。
一致性视图
在表的每一列中都存放着两个隐藏列:trx_id
和 roll_ptr
,分别表示修改当前列的事务ID和指向上一个版本的记录,如此就可以组成一个版本链。
接下来就可以讲 ReadView
了。它存储了一种用来记录当前活跃状态的读写事务,用于判定改事务的可见的数据版本。
它有三个重要的概念:
up_limit_id
:代表当前已提交的事务IDtrx_ids
:当前活跃但未提交的事务IDlow_limit_id
:当前最大的事务ID+1
因为 low_limit_id
和 trx_ids
要不就是 ReadView
创建之后的事务,要不就是当前未提交的事务ID集合。所以这两个都是不可见的。
Read Commited
和 Reaptable Read
的区别就在于你每次进行读操作的时候是否重新生成一个 ReadView
。
- 如果重新生成
ReadView
的话,就代表每次读取的时候都会获得已提交的事务修改的内容,即up_limit_id
会更新为最新的trx_id
,也就是说是Read Commited
隔离级别