MVCC多版本并发控制
1. 什么是MVCC
mvcc中文名位多版本并发控制,是数据库引擎处理读写冲突的一种手段,目的在于提高并发场景下数据库的吞吐量。
通过mvcc机制,在多个事务并发执行时,select可以无需加锁,而是通过mvcc机制读取指定版本的历史记录,可以保证读取的值符合事务所处的隔离级别。从而解决并发场景下的读写冲突。
在mysql数据库中,mvcc可以在读已提交和可重复读两种隔离级别下使用。
2. 为什么需要MVCC
事务并发会导致一系列问题:丢失更新、脏读、不可重复读、幻读。数据库可以通过隔离级别来应对,实现隔离级别有两种方式:
- 加读写锁
- mvcc【针对于select,更新还得加写锁】
但本质上,隔离级别是一种在并发性能和并发产生的副作用间的妥协。
3. mvcc的实现原理
InnoDB引擎是通过每个表的两个隐藏字段实现的:
- DATA_TRX_ID:记录更新这条记录的事务ID
- DATA_ROLL_PTR:指向改行上一次的数据,在undo日志中以链表形式组织
此外InnoDB还有一个隐藏字段:
- DB_ROW_ID:如果表没有主键,此列会出现作为隐藏主键。
MVCC的判断流程如下:
ReadView:是当前活动事务ID的列表[minid, maxid]
- 如果被访问数据的DATA_TRX_ID小于minid,说明该版本的数据在ReadView生成前,已经提交,可以直接返回
- 如果访问数据的DATA_TRX_ID大于maxid, 说明该版本的数据在ReadView生成后才生成,需要根据undo寻找上一个版本,继续判断
- 如果访问数据的DATA_TRX_ID在minid和maxid之间,
- 若DATA_TRX_ID在ReadView中,说明创建ReadView时,该版本所属事务尚未提交,需要寻找上一个版本
- 若DATA_TRX_ID不在ReadView中,说明创建ReadView时,该版本所属事务已经提交,可以直接返回
RC和RR两个隔离级别下一个很大的不同是:ReadView生成时间点不同,RC下每次select都会生成一个ReadView,事务执行期间会更新;而RR只在第一个select语句时生成一个ReadView,事务执行期间,不会更新。
原文作者: NTJD
原文链接: http://yoursite.com/2020/09/15/MVCC多版本并发控制/
版权声明: 转载请注明出处(必须保留作者署名及链接)