整理知识点,有四种隔离级别,也要知道每种的实现原理。。emmm
Multi-Version Concurrency Control 多版本并发控制,MVCC 是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问;在编程语言中实现事务内存。它使得大部分支持行锁的事务引擎,不再单纯的使用行锁来进行数据库的并发控制,取而代之的是把数据库的行锁与行的多个版本结合起来,只需要很小的开销,就可以实现非锁定读,从而大大提高数据库系统的并发性能
一句话讲,MVCC就是用 这里留意到 MVCC 关键的两个点:
|
MVCC使用的快照保存在日志中,该日志通过回滚指针把一个数据行的所有快照连接起来。
● redo log
MySQL在开启事务时,会将执行的SQL保存到指定的log文件,即redo log。当MySQL执行recovery时执行redo log里的SQL操作即可。redo log不会被立即写入磁盘,会先写入redo buffer;当客户端执行commit时,redo buffer的内容会视情况存入磁盘。
● undo log
与redo log相反,undo log是为了回滚事务而写的日志,具体内容就是copy事务开始前的数据(行)到undo buffer。
与redo buffer一样,undo buffer也是环形缓冲,当缓冲满的时候buffer内容会被刷新到磁盘。
与redo log不同的是,undo log没有独立的磁盘文件,所有的undo log均被存在主ibd数据文件中(表空间)。
快照读:读取的是快照版本,也就是历史版本,MVCC读取的是快照中的数据,可以减少加锁带来的开销。
当前读:读取的是最新版本,读的是最新数据,需要加锁。
普通的SELECT就是快照读,而UPDATE、DELETE、INSERT、SELECT ... LOCK IN SHARE MODE、SELECT ... FOR UPDATE是当前读。
五、 实现过程
innodb MVCC主要是为Repeatable-Read事务隔离级别做的。在此隔离级别下,A、B客户端所示的数据相互隔离,互相更新不可见
了解innodb的行结构、Read-View的结构对于理解innodb mvcc的实现由重要意义具体的执行过程
begin->用排他锁锁定该行->记录redo log->记录undo log->修改当前行的值,写事务编号,回滚指针指向undo log中的修改前的行
上述过程确切地说是描述了UPDATE的事务过程,其实undo log分insert和update undo log,因为insert时,原始的数据并不存在,所以回滚时把insert undo log丢弃即可,而update undo log则必须遵守上述过程
下面分别以select、delete、 insert、 update语句来说明
关键:开启一个事务时,该事务版本号肯定大于当前所有数据行的创建版本号
SELECT
Innodb检查每行数据,确保他们符合两个标准:
1、InnoDB只查找版本早于当前事务版本的数据行(也就是数据行的版本必须小于等于事务的版本),这确保当前事务读取的行都是事务之前已经存在的,或者是由当前事务创建或修改的行
2、行的删除操作的版本一定是未定义的或者大于当前事务的版本号,确定了当前事务开始之前,行没有被删除
符合了以上两点则返回查询结果。
INSERT
InnoDB为每个新增行记录当前系统版本号作为创建ID。
DELETE
InnoDB为每个删除行的记录当前系统版本号作为行的删除ID。
UPDATE
新插入一行(复制了要删除的记录),并以当前事务的版本号作为新行的创建版本号,同时将原记录行的删除版本号设置为当前事务版本号
说明
insert操作时 “创建时间”=DB_ROW_ID,这时,“删除时间 ”是未定义的;
update时,复制新增行的“创建时间”=DB_ROW_ID,删除时间未定义,旧数据行“创建时间”不变,删除时间=该事务的DB_ROW_ID;
delete操作,相应数据行的“创建时间”不变,删除时间=该事务的DB_ROW_ID;
select操作对两者都不修改,只读相应的数据
六、对于MVCC的总结
上述更新前建立undo log,根据各种策略读取时非阻塞就是MVCC,undo log中的行就是MVCC中的多版本,这个可能与我们所理解的MVCC有较大的出入,一般我们认为MVCC有下面几个特点: