MVCC(Multi-Version Concurrency Control,多版本并发控制)是一种用于解决数据库事务并发问题的机制,能够支持高效的读写操作。它通过为每条记录维护多个版本,保证事务间互不干扰,实现高性能的并发控制。
MVCC基本概念
- 核心思想:
每次对数据的修改(如插入、更新、删除)都会生成一个新的版本,而不是直接覆盖原来数据。读操作则根据事务的快照读取数据的合适版本,从而避免阻塞读操作。 特点:
- 读写分离:读操作不会阻塞写操作,写操作也不会阻塞读操作。
- 基于时间戳或事务 ID:每个事务在开始时获取一个时间戳或事务 ID,用于确定其可见的数据版本。
InnoDB中的MVCC的实现
MySQL 的 InnoDB 存储引擎通过 MVCC 支持事务隔离级别 READ COMMITTED 和 REPEATABLE READ。
- 数据行的隐藏字段
在 InnoDB 中,每条记录除了用户定义的字段,还包含以下两个隐藏字段:
- trx_id(事务 ID):记录最后一次修改该行的事务 ID。
- roll_pointer(回滚指针):指向 Undo Log(回滚日志)的指针,用于定位之前的数据版本。
- Undo Log(回滚日志)
- 每次修改数据时,会在 Undo Log 中记录旧版本的数据。
- 通过 roll_pointer 链接多个版本,从而形成一个版本链。
Undo Log 的作用:
- 支持事务回滚。
- 提供历史版本数据,供其他事务读取。
- 示例:
- 假设事务依次更新一条记录,生成如下版本链:
Row (Current Version) -> Row (Old Version 1) -> Row (Old Version 2) -> ...
- 可见性判断规则
一个事务在读取数据时,会判断某个版本是否对其可见,判断依据是 当前事务的快照(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 在活跃事务列表中:表示该版本对应的事务尚未提交,因此不可见。
- 各隔离级别下的实现
READ COMMITTED:
- 每次查询都会创建一个新的快照,确保读取的是最新已提交数据。
- 不支持可重复读(同一事务两次查询结果可能不同)。
REPEATABLE READ(MySQL 默认):
- 在事务开始时创建一次快照,确保整个事务期间读取的是同一版本数据。
- 支持可重复读,通过版本链避免幻读。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。