首页 > 数据库 > MySQL > 值得收藏,揭秘 MySQL 多版本并发控制实现原理
MySQL 中多版本并发控制(MVCC),是现代数据库引擎实现中常用的处理读写冲突的手段,MVCC 作为 MySQL 高级应用特性,目的在于提高数据库高并发场景下的吞吐性能。

脏读:一个事务读取到了另外一个事务没有提交的数据;
不可重复读:在同一事务中,两次读取同一数据,得到内容不同;
幻读:同一事务中,用同样的操作读取两次,得到的记录数不相同。
乐观锁:
其实现如同它的名字一样,是假设比较好的情况。
我们可以通过比较版本号决定数据是否显示出来(具体的规则后面会介绍到),读取数据的时候不需要加锁也可以保证事务的隔离效果。
当前读:
当前读就是读取最新数据,而不是历史版本的数据。
加锁的SELECT,或者对数据进行增删改都会进行当前读(包括加锁的读取和DML操作)。



首先获取事务自己的版本号,也就是事务 ID;
获取 Read View;
查询得到的数据,然后与 Read View 中的事务版本号进行比较;
如果不符合 ReadView 规则,就需要从 Undo Log 中获取历史快照;
最后返回符合规则的数据。

up_limit_id,活跃的事务中最小的事务 ID;
trx_ids,系统当前正在活跃的事务 ID 集合;
low_limit_id,活跃的事务中最大的事务 ID;
creator_trx_id,创建这个 Read View 的事务 ID。
DB_ROW_ID :
6-byte,记录操作该数据事务的事务ID;
DB_TRX_ID :
6-byte,当创建表没有合适的索引作为聚集索引时,会用该隐藏ID创建聚集索引;
DB_ROLL_PTR :
7-byte,回滚指针,指向上一个版本数据在undo log 里的位置指针;
五、InnoDB是如何解决幻读的?
我们同时开启事务 A 和事务 B,先在事务 A 中进行某个条件范围的查询,读取的时候采用排它锁,在事务 B 中增加一条符合该条件范围的数据,并进行提交,然后我们在事务 A 中再次查询该条件范围的数据,就会发现结果集中多出一个符合条件的数据,这样就出现了幻读。
记录锁:
针对单个行记录添加锁。
间隙锁(Gap Locking):
可以锁住一个范围(索引之间的空隙),但不包括记录本身。
采用间隙锁的方式可以防止幻读情况的产生。
Next-Key 锁:
锁住一个范围,同时锁定记录本身,相当于间隙锁 + 记录锁,可以解决幻读的问题。

MVCC 的核心就是 Undo Log+ Read View。
“MV”就是通过 Undo Log 来保存数据的历史版本,实现多版本的管理;
“CC”是通过 Read View 来实现管理,通过 Read View 原则来决定数据是否显示。
同时针对不同的隔离级别,Read View 的生成策略不同,也就实现了不同的隔离级别。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70024420/viewspace-2926163/ ,如需转载,请注明出处,否则将追究法律责任。