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_id:m_ids中最小的事务ID。max_trx_id:下一个将分配给事务的ID值。creator_trx_id:生成该ReadView的事务的事务ID。
1.3 判断版本是否可见
- 如果被访问版本的
trx_id与 ReadView 中的creator_trx_id相同,表示当前事务在访问自己修改过的记录,版本可见。 - 如果被访问版本的
trx_id小于 ReadView 中的min_trx_id,表示生成版本的事务在当前事务生成ReadView前已提交,版本可见。 - 如果被访问版本的
trx_id大于或等于 ReadView 中的max_trx_id,表示生成版本的事务在当前事务生成ReadView后才开启,版本不可见。 - 如果被访问版本的
trx_id在min_trx_id和max_trx_id之间,判断是否在m_ids列表中,如果在,版本不可见;如果不在,版本可见。 - 如果某个版本对当前事务不可见,则沿着版本链找到下一个版本,重复以上步骤,直到版本链的最后一个版本。如果最后一个版本仍不可见,则记录对当前事务不可见。
1.4 生成 ReadView 的时机
-
READ COMMITTED:
- 每次读取数据前都生成一个 ReadView。
-
REPEATABLE READ:
- 在第一次读取数据时生成一个 ReadView。
2. 举例说明
假设有一个聚簇索引记录,事务100和事务200对该记录进行UPDATE操作。每次对记录进行改动,都会记录一条undo日志,构建版本链。
- 事务100修改记录,生成版本A。
- 事务200修改记录,生成版本B,undo日志指向版本A。
- 事务100再次修改记录,生成版本C,undo日志指向版本B。
版本链:A -> B -> C
- 当某个事务访问这条记录时,ReadView中的
creator_trx_id为该事务的ID,判断版本是否可见的逻辑会按照上述步骤进行。
这样的机制保证了不同事务之间对数据的隔离性,使得各个事务看到的数据是一致的,同时提高了并发访问的效率。