mysql MVCC 多版本控制
-
什么是MVCC?
-
MVCC用来解决什么问题?
-
MVCC是怎么实现的?
什么是MVCC
*多版本并发控制 *
多版本并发控制(Multi-Version Concurrency Control,MVCC),是MySQL提高性能的一种方式,配合Undo日志和版本链,让不同事务的读-写、写-读操作可以并发执行,从而提升系统性能。一般在使用 读已提交(READ COMMITTED)和 可重复读(REPEATABLE READ)隔离级别的事务中实现
在InnoDB中,会在聚集索引中(主键索引)每行数据后添加额外的隐藏的值来实现MVCC。
-
TRX_ID:6字节的DB_TRX_ID字段表示插入或更新该行的最后一次操作的标识符。每次对某条聚集索引记录进行改动时,都会把对应的事务id赋值给TRX_ID隐藏列。删除在内部被视为更新,在该更新中,行中的特殊位被设置为将其标记为已删除。
-
ROLL_PTR:7字节的 DB_ROLL_PTR字段,称为回滚指针。回滚指针指向写入回滚段的撤消日志记录。每次对某条聚簇索引记录进行改动时,都会把旧的版本写入到Undo日志中,然后这个隐藏列就相当于一个指针,可以通过它来找到该记录修改前的信息。
-
ROW_ID:6字节的DB_ROW_ID字段包含一个行ID,该ID在插入新行时会自动增加。此字段不是必须的,当聚集索引中的主键是由MySQL自动生成的自增主键时,才会存在
MVCC 解决了什么问题
MVCC指的就是在使用 读已提交(READ COMMITTED)、可重复读(REPEATABLE READ)这两种隔离级别的事务时,在执行普通的SEELCT操作时访问记录的版本链的过程中,可以让不同事务的读-写、写-读操作并发执行,从而提升系统性能
一致性非锁定读也是基于MVCC
MVCC 是怎么实现的
MVCC的实现是通过undo log和read view来实现的
Read View
ReadView组成:
m_ids:表示在生成ReadView时当前系统中活跃的读写事务的事务id列表。
min_trx_id:表示在生成ReadView时当前系统中活跃的读写事务中最小的事务id,也就是m_ids中的最小值。
max_trx_id:表示生成ReadView时系统中应该分配给下一个事务的id值。
creator_trx_id:表示生成该ReadView的事务的事务id
RR 和 RC 生成Read View 时间点不同:
READ COMMITTD
在每一次进行普通SELECT操作前都会生成一个ReadView。REPEATABLE READ
只在首次进行普通SELECT操作前生成一个ReadView,之后的查询操作都重复使用这个ReadView
在RR隔离级别下
因为在RR隔离级别下, 当前session下查询时生成的Read View是同一个,即是首次查询的ReadView
初始数据:
mysql> select * from t_game where id=1;
+----+---------+
| id | name |
+----+---------+
| 1 | 王者荣耀 |
+----+---------+
1 row in set (0.00 sec)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PJAUhS2u-1619860758409)(image-20210501171631581.png)]
如图有3个事务:
mysql> SELECT TRX_ID FROM INFORMATION_SCHEMA.INNODB_TRX;
+-----------------+
| TRX_ID |
+-----------------+
| 95886 |
| 95885 |
| 95884 |
+-----------------+
6 rows in set (0.00 sec)
undo log
:
以 当transaction3 提交事务之后查询为例:
- 此时 undo log 上记录的数据有 【1,2】两条,mysql 从最新一条匹配,
trx_id[95886]
在Read View
的 min 和 max 之间, 符合Read View
条件3 - 但是
trx_id[95886]
不在m_ids[95884,95885]
内, 所以这条数据对于这次查询是可见的,即查询结果显示 王者荣耀1