mysql innodb中MVCC理解和redo,undo log详解

目录

 

简介

插入

删除数据

修改

查找

undo log 和 redo log

undo log

redo log


简介

MVCC(Multiversion Concurrency Control),即多版本并发控制技术,它使得大部分支持行锁的事务引擎,不再单纯的使用行锁来进行数据库的并发控制,取而代之的是把数据库的行锁与行的多个版本结合起来,只需要很小的开销,就可以实现非锁定读,从而大大提高数据库系统的并发性能。

MVCC目的是并发访问(读或写)数据库时,对正在事务内处理的数据做多版本的管理。以达到用来避免写操作的堵塞,从而引发读操作的并发问题。

在mysql中,事务创建的时候,会默认创建一个全局的事务ID,下面就将事务中数据插入,修改,删除和查询来具体说明:

在mysql数据中,会有一个DB_TRX_ID和DB_ROLL_PT两个字段。

DB_TRX_ID是数据添加时候的全局事务ID号,DB_ROLL_PT是该行数据删除的时候全局事务ID号。

以下是一个通过事务插入数据的例子:

插入

插入数据规则:插入时候,在数据行版本号增加当前系统全局事务ID号

 但通过事务插入新的数据时候,数据行版本号(DB_TRX_ID)为当前事务版本号,删除版本号设置为NULL。

删除数据

规则:删除:在删除版本号增加当前系统全局事务ID号

如上图,在事务中删除id为2的数据,那么在数据的删除版本号中增加当前删除版本号。 

修改

规则:先做命中的数据行的复制,然后间原行数据的删除版本号设置为当前全局事务ID,新的行数据的数据行版本号也设置为当前全局事务ID,删除版本号为NULL

如上图,在事务中更改id为1的数据信息, 先复制元数据,然后将元数据删除版本号改为当前事务全局版本号,再插入新的数据,将数据行版本号设置为当前版本号。

查找

规则:1.寻找数据行版本号小于或者等于当前全局事务ID(这样可以确认事务读取的行在开始前已经存在,或者是事务自身插入或者修改的),2.查找删除版本号为NULL,或者大于当前事务版本号的ID(即确保读取出来的行在此事务开启之前没有被删除)

 

通过上面的规则我们可以看出来,当 删除版本号不为NULL的时候那么该数据就存在,当数据行版本号中的数据小于当前执行事务的事务ID号的时候,那么此时该数据对此事务是可见的。

所以查询的时候第一个就是要查询查询数据版本号小于该事务的全局事务ID,另一个就是它的删除版本号要么为NULL,要么大于当前事务全局事务ID,当为NULL时候,说明该条数据存在,当大于该事务全局事务ID的时候,说明,执行该事务的时候,数据还存在。

MVCC就是通过这样的逻辑来处理并发事务的。

undo log 和 redo log

mysql的事务日志包括undo log 和redo log

undo log

undo log是指事务开始之前,在操作任何数据之前,首先将需操作的数据备份到一个地方 (Undo Log)。

在执行事务的时候,我们知道当调用roll back命令的时候,数据就会还原,这里用到的原理就是undo,也是实现事务原子性的原理。

事务处理过程中如果出现了错误或者用户执行了 ROLLBACK语句,Mysql可以利用Undo Log中的备份将数据恢复到事务开始之前的状态。

UndoLog在Mysql innodb存储引擎中用来实现多版本并发控制:事务未提交之前,Undo保存了未提交之前的版本数据,Undo 中的数据可作为数据旧版本快照供其他并发事务进行快照读

在事务执行之前,会现在缓存中的undo buffer备份旧的数据,当备份数据大小达到一定程度的时候,或者备份数据长时间没有更改的时候,就会生成undo log写入磁盘。

redo log

redo log:redo log 和undo log相对应,它是将事务操作的最新数据存储起来。

redo log主要是为了实现事务的持久性而产生的。防止在发生故障的时间点,尚有脏页未写入磁盘,在重启mysql服务的时候,根据redo log进行重做,从而达到事务的未入磁盘数据进行持久化这一特性。

redo 里面策略设置,一个就是日志文件的大小,另一个就是缓存池的大小。由于一旦事务提交之后且数据持久化落盘之后,redo log数据就没有意义了,所以redo log中数据是循环写入的。

指定Redo log日志文件组中的数量 innodb_log_files_in_group 默认为2

指定Redo log每一个日志文件最大存储量innodb_log_file_size 默认48M

指定Redo log在cache/buffer中的buffer池大小innodb_log_buffer_size 默认16M

Redo buffer 持久化Redo log的策略, Innodb_flush_log_at_trx_commit:
取值 0 每秒提交 Redo buffer --> Redo log OS cache -->flush cache to disk[可能丢失一秒内的事务数据]
取值 1 默认值,每次事务提交执行Redo buffer --> Redo log OS cache -->flush cache to disk[最安全,性能最差的方式]取值 2 每次事务提交执行Redo buffer --> Redo log OS cache 再每一秒执行 ->flush cache to disk操作

猜你喜欢

转载自blog.csdn.net/harryptter/article/details/87388164