深入理解MySQL系列之redo log、undo log和binlog

redo log保证事务的持久性,undo log用来帮助事务回滚及MVCC的功能。

InnoDB存储引擎体系结构

深入理解MySQL系列之redo log、undo log和binlog

深入理解MySQL系列之redo log、undo log和binlog

redo log Write Ahead Log策略

事务提交时,先写重做日志再修改页;当由于发生宕机而导致数据丢失时,就可以通过重做日志来完成数据的恢复。

InnoDB首先将重做日志信息先放到重做日志缓存

按一定频率刷新到重做日志文件

重做日志文件: 在默认情况,InnoDB存储引擎的数据目录下会有两个名为ib_logfile1和ib_logfile2的文件。每个InnoDB存储引擎至少有1个重做日志文件组(group),每个文件组下至少有2个重做日志文件。

下面图一,很好说明重做日志组以循环写入方式运行,InnoDB存储引擎先写ib_logfile1,当达到文件最后时,会切换至重做日志文件ib_logfile2.

而图2,增加一个OS Buffer,有助于理解fsync过程。

深入理解MySQL系列之redo log、undo log和binlog

在这里插入图片描述

关于log group,称为重做日志组,是一个逻辑上的概念。InnoDB存储引擎实际只有一个log group。

深入理解MySQL系列之redo log、undo log和binlog

log group中第一个redo log file,其前2KB部分保存4个512字节大小块:

深入理解MySQL系列之redo log、undo log和binlog

重做日志缓冲刷新到磁盘

下面三种情况刷新:

Master Thread每一秒将重做日志缓冲刷新到重做日志文件

每个事务提交时会将重做日志缓冲刷新到重做日志文件

当重做日志缓冲池剩余空间小于1/2时,重做日志刷新到重做日志文件

补充上述三种情况第二种,触发写磁盘过程由参数innodb_flush_log_at_trx_commit控制,表示提交(commit)操作时,处理重做日志的方式。

参数innodb_flush_log_at_trx_commit有效值有0、1、2

0表示当提交事务时,并不将事务的重做日志写入磁盘上日志文件,而是等待主线程每秒刷新。

1表示在执行commit时将重做日志缓冲同步写到磁盘,即伴有fsync的调用

2表示将重做日志异步写到磁盘,即写到文件系统的缓存中。不保证commit时肯定会写入重做日志文件。

0,当数据库发生宕机时,部分日志未刷新到磁盘,因此会丢失最后一段时间的事务。
2,当操作系统宕机时,重启数据库后会丢失未从文件系统缓存刷新到重做日志文件那部分事务。

下图有助于理解

在这里插入图片描述

重做日志块

在InnoDB存储引擎中,重做日志都是以512字节进行存储的。意味着重做日志缓存、重做日志文件都是以块(block)的方式进行保存的,每块512字节。

重做日志头12字节,重做日志尾8字节,故每个重做日志块实际可以存储492字节。

深入理解MySQL系列之redo log、undo log和binlog

重做日志格式

redo log是基于页的格式来记录的。默认情况下,innodb的页大小是16KB(由 innodb_page_size变量控制),一个页内可以存放非常多的log block(每个512字节),而log block中记录的又是数据页的变化。

log body的格式分为4部分:

redo_log_type:占用1个字节,表示redo log的日志类型。

space:表示表空间的ID,采用压缩的方式后,占用的空间可能小于4字节。

page_no:表示页的偏移量,同样是压缩过的。

redo_log_body表示每个重做日志的数据部分,恢复时会调用相应的函数进行解析。例如insert语句和delete语句写入redo log的内容是不一样的。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpzzzp.html