Mysql事务原理&MVCC
1、总结先行
Mysql的Innodb存储通过MVCC乐观锁的方式来保证了可重复读隔离级别下事务的幻读问题
MVCC的核心就是Undo Log+ Read View,“MV”就是通过Undo Log来保存数据的历史版本,实现多版本的管理,“CC”是通过Read View来实现管理,通过Read View原则来决定数据是否显示。同时针对不同的隔离级别,Read View的生成策略不同,也就实现了不同的隔离级别
2、事务的隔离级别和异常问题
隔离级别/异常 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | ✅ | ✅ | ✅ |
读已提交 | ❌ | ✅ | ✅ |
可重复读 | ❌ | ❌ | ✅ |
串行化 | ❌ | ❌ | ❌ |
在MySQL中,默认的隔离级别是可重复读,可以解决脏读和不可重复读的问题,但不能解决幻读问题。如果我们想要解决幻读问题,就需要采用串行化的方式,也就是将隔离级别提升到最高,但这样一来就会大幅降低数据库的事务并发能力。
- 哪Mysql中是咋么在可重复读隔离级别解决幻读的呢?
- 答案是: MVCC + Next-Key Lock
3、MVCC简介
MVCC的英文全称是Multiversion Concurrency Control,中文翻译过来就是多版本并发控制技术。从名字中也能看出来,MVCC是通过数据行的多个版本管理来实现数据库的并发控制,简单来说它的思想就是保存数据的历史版本。这样我们就可以通过比较版本号决定数据是否显示出来(具体的规则后面会介绍到),读取数据的时候不需要加锁也可以保证事务的隔离效果。
通过MVCC我们可以解决以下几个问题:
- 读写之间阻塞的问题,通过MVCC可以让读写互相不阻塞,即读不阻塞写,写不阻塞读,这样就可以提升事务并发处理能力。
- 降低了死锁的概率。这是因为MVCC采用了乐观锁的方式,读取数据时并不需要加锁,对于写操作,也只锁定必要的行。
- 解决一致性读的问题。一致性读也被称为快照读,当我们查询数据库在某个时间点的快照时,只能看到这个时间点之前事务提交更新的结果,而不能看到这个时间点之后事务提交的更新结果。
3.1、快照读&当前读
那么什么是快照读呢?快照读读取的是快照数据。不加锁的简单的SELECT都属于快照读,比如这样:
SELECT * FROM player WHERE ... |
当前读就是读取最新数据,而不是历史版本的数据。加锁的SELECT,或者对数据进行增删改都会进行当前读,比如:
SELECT * FROM player LOCK IN SHARE MODE; |
这里需要说明的是,快照读就是普通的读操作,而当前读包括了加锁的读取和DML操作。
4、InnoDB中MVCC的实现
4.1、事务版本号
4.2、行记录的隐藏列
4.3、Undo Log
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 月怿姝雪颜!
评论
Disquslivere