什么是MVCC
MVCC(Multi-Version Concurrency Control,多版本并发控制)是一种并发控制机制,允许多个事务同时读取和写入数据库,而无需相互等待,从而提高数据库的并发性能。
MVCC机制的实现
通过readView和undo log实现MVCC。
MVCC实际上不是真的存储了多个版本的数据,只是借助undo log记录每次写操作的反向操作,根据反向操作得到数据的历史版本。
readView
用来判断哪个版本对当前事务可见。可见版本是从最新版开始沿着版本链逐渐寻找老的版本,遇到符合版本就返回
- trx_id:当前事务id
- creator_trx_id:当前事务id
- m_ids:生成readView时还活跃的事务id集合,也就是已经启动但是还未提交的事务id集合
- min_trx_id:当前活跃id的最小值
- max_trx_id:生成readView时InnoDB将分配给下一个事务的id值(事务id是递增的)
判断条件
- 如果当前数据版本的trx_id=creator_trx_id,说明修改这个数据的事务就是当前事务,可见。
- 如果当前数据版本的trx_id<min_trx_id,说明修改这个数据的事务在当前生成readView时已经提交了,可见。
- 如果当前数据版本的trx_id在min_trx_id和max_trx_id之间
- trx_id在m_ids中,说明修改这个数据的事务还未提交,不可见。
- trx_id不在m_ids中,说明修改这个数据的事务已经提交,可见。
- 如果当前数据版本的trx_id>max_trx_id,说明修改这个数据的事务在当前生成readView时还未启动,不可见。
当前读与快照读
- 当前读
- select...lock in share mode
- select...for update
- insert...
- update...
- delete...
- 快照读
- select
当前读就是读取最新数据,所以加锁的select和数据的增删改都是当前读,快照读就是读取快照数据。
只有读已提交(RC read commit)和可重复读(RR repeatable read)隔离级别会使用快照读。
读已提交(RC read commit)隔离级别下的MVCC
每次读取都会生成一个快照,总是读取行的最新版本。
可重复读(RR repeatable read)隔离级别下的MVCC
快照会在事务开始时生成,只有对事务中数据进行修改才会更新快照。
