阅读前说明:关于mysql的MVCC理解因为没有参考专业的书籍(看过的《高性能mysql》和《mysql》技术内幕都没有相关介绍,难道是我看到?),所以对于这一块的理解完全出自自己的理解(也参考了其他博友的文章),如果哪里有问题,欢迎一起探讨。
Undo和Redo
在理解mvcc前应该要先知道这两个概念。
1. Undo Log
Undo Log 是什么: undo意为取消,以撤销操作为目的,返回指定某个状态的操作 undo log指事务开始之前,在操作任何数据之前,首先将需操作的数据备份到一个地方 (Undo Log)
UndoLog是为了实现事务的原子性而出现的产物
Undo Log实现事务原子性:
事务处理过程中如果出现了错误或者用户执行了 ROLLBACK语句,Mysql可以利用Undo Log中的备份 将数据恢复到事务开始之前的状态
UndoLog在Mysql innodb存储引擎中用来实现多版本并发控制(能实现MVCC的基础):
事务未提交之前,Undo保存了未提交之前的版本数据,Undo 中的数据可作为数据旧版本快照供 其他并发事务进行快照读
1.1. 快照读,当前读
快照读:SQL读取的数据是快照版本,也就是历史版本,普通的SELECT就是快照读 innodb快照读,数据的读取将由 cache(原本数据) + undo(事务修改过的数据) 两部分组成
当前读:SQL读取的数据是最新版本。通过锁机制来保证读取的数据无法通过其他事务进行修改 UPDATE、DELETE、INSERT、SELECT … LOCK IN SHARE MODE、SELECT … FOR UPDATE都是 当前读
2. Redo Log
Redo Log 是什么: Redo,顾名思义就是重做。以恢复操作为目的,重现操作; Redo log指事务中操作的任何数据,将最新的数据备份到一个地方
(Redo Log) Redo log的持久: 不是随着事务的提交才写入的,而是在事务的执行过程中,便开始写入redo 中。具体 的落盘策略可以进行配置
RedoLog是为了实现事务的持久性而出现的产物
Redo Log实现事务持久性: 防止在发生故障的时间点,尚有脏页未写入磁盘,在重启mysql服务的时候,根据redo log进行重做,从而达到事务的未入磁盘数据进行持久化这一特性。
MVCC的流程
其实我对mvcc的理解很简单,就是一种对于乐观锁的实现。他有两个关键的隐藏的版本字段。
DB_ROW_ID 6字节:行标识
DB_TRX_ID 6字节:插入或更新行的最后一个事务的事务ID,自动递增 (创建版本号)
DB_ROLL_PTR 7字节:回滚指针(删除版本号)
DB_TRX_ID 和DB_ROLL_PTR 是两个关键的控制版本的字段。
下面看下如何通过这两个字段来进行多版本并发控制的:
因为博客篇幅有限,我用processon画的流程图说明:
mvcc流程图