MVCC 原理、举例说明

127 阅读2分钟

MVCC(Multi-Version Concurrency Control)是数据库系统中常用的一种并发控制机制,用于提供不同事务间的隔离性。下面对MVCC的原理和相关概念进行总结:

1. MVCC 原理

1.1 版本链

  • InnoDB聚簇索引记录中的隐藏列:

    • trx_id:每个事务对聚簇索引记录进行修改时,将该事务的事务ID赋值给 trx_id 隐藏列。
    • roll_pointer:每次修改聚簇索引记录时,将旧版本的数据写入undo日志,并通过 roll_pointer 隐藏列作为指针,构建一个版本链。

1.2 ReadView

  • 由四个关键属性组成:

    • m_ids:当前系统中活跃的读写事务的事务ID列表。
    • min_trx_idm_ids中最小的事务ID。
    • max_trx_id:下一个将分配给事务的ID值。
    • creator_trx_id:生成该ReadView的事务的事务ID。

1.3 判断版本是否可见

  1. 如果被访问版本的 trx_id 与 ReadView 中的 creator_trx_id 相同,表示当前事务在访问自己修改过的记录,版本可见。
  2. 如果被访问版本的 trx_id 小于 ReadView 中的 min_trx_id,表示生成版本的事务在当前事务生成ReadView前已提交,版本可见。
  3. 如果被访问版本的 trx_id 大于或等于 ReadView 中的 max_trx_id,表示生成版本的事务在当前事务生成ReadView后才开启,版本不可见。
  4. 如果被访问版本的 trx_idmin_trx_idmax_trx_id 之间,判断是否在 m_ids 列表中,如果在,版本不可见;如果不在,版本可见。
  5. 如果某个版本对当前事务不可见,则沿着版本链找到下一个版本,重复以上步骤,直到版本链的最后一个版本。如果最后一个版本仍不可见,则记录对当前事务不可见。

1.4 生成 ReadView 的时机

  • READ COMMITTED:

    • 每次读取数据前都生成一个 ReadView。
  • REPEATABLE READ:

    • 在第一次读取数据时生成一个 ReadView。

2. 举例说明

假设有一个聚簇索引记录,事务100和事务200对该记录进行UPDATE操作。每次对记录进行改动,都会记录一条undo日志,构建版本链。

  1. 事务100修改记录,生成版本A。
  2. 事务200修改记录,生成版本B,undo日志指向版本A。
  3. 事务100再次修改记录,生成版本C,undo日志指向版本B。

版本链:A -> B -> C

  • 当某个事务访问这条记录时,ReadView中的 creator_trx_id 为该事务的ID,判断版本是否可见的逻辑会按照上述步骤进行。

这样的机制保证了不同事务之间对数据的隔离性,使得各个事务看到的数据是一致的,同时提高了并发访问的效率。