MySQL-MVCC

leard 发布于 2025-06-01 1 次阅读


什么是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

快照会在事务开始时生成,只有对事务中数据进行修改才会更新快照。