MVCC(Multi-Version Concurrency Control,多版本并发控制)是一种用于解决数据库事务并发问题的机制,能够支持高效的读写操作。它通过为每条记录维护多个版本,保证事务间互不干扰,实现高性能的并发控制。

MVCC基本概念

  • 核心思想:
    每次对数据的修改(如插入、更新、删除)都会生成一个新的版本,而不是直接覆盖原来数据。读操作则根据事务的快照读取数据的合适版本,从而避免阻塞读操作。
  • 特点:

    • 读写分离:读操作不会阻塞写操作,写操作也不会阻塞读操作。
    • 基于时间戳或事务 ID:每个事务在开始时获取一个时间戳或事务 ID,用于确定其可见的数据版本。

InnoDB中的MVCC的实现

MySQL 的 InnoDB 存储引擎通过 MVCC 支持事务隔离级别 READ COMMITTED 和 REPEATABLE READ。

  1. 数据行的隐藏字段
  • 在 InnoDB 中,每条记录除了用户定义的字段,还包含以下两个隐藏字段:

    • trx_id(事务 ID):记录最后一次修改该行的事务 ID。
    • roll_pointer(回滚指针):指向 Undo Log(回滚日志)的指针,用于定位之前的数据版本。
  1. Undo Log(回滚日志)
  • 每次修改数据时,会在 Undo Log 中记录旧版本的数据。
  • 通过 roll_pointer 链接多个版本,从而形成一个版本链。
  • Undo Log 的作用:

    • 支持事务回滚。
    • 提供历史版本数据,供其他事务读取。
  • 示例:
  • 假设事务依次更新一条记录,生成如下版本链:
Row (Current Version) -> Row (Old Version 1) -> Row (Old Version 2) -> ...
  1. 可见性判断规则

一个事务在读取数据时,会判断某个版本是否对其可见,判断依据是 当前事务的快照(Snapshot),与以下条件相关:

关键字段:

(1) 当前事务ID(current_txn_id): 事务开始时分配的唯一ID。
(2) trx_id(版本的事务 ID):表示该版本由哪个事务创建。
(3) 活跃事务列表:表示当前正在运行的事务集合。

可见性规则:

  • trx_id < current_txn_id 且事务已提交:表示该版本由其他事务创建且已提交,因此可见。
  • trx_id = current_txn_id:表示该版本是当前事务自己创建的,因此可见。
  • trx_id > current_txn_id:表示该版本是由尚未启动的事务创建,不可见。
  • trx_id 在活跃事务列表中:表示该版本对应的事务尚未提交,因此不可见。
  1. 各隔离级别下的实现
  • READ COMMITTED:

    • 每次查询都会创建一个新的快照,确保读取的是最新已提交数据。
    • 不支持可重复读(同一事务两次查询结果可能不同)。
  • REPEATABLE READ(MySQL 默认):

    • 在事务开始时创建一次快照,确保整个事务期间读取的是同一版本数据。
    • 支持可重复读,通过版本链避免幻读。

爱跑步的猕猴桃
1 声望0 粉丝