前面已经学了了rodo log,可以知道redo log(即log block)的组成
下面认识一下log group,log group其实为重做日志组,其中有多个重做日志,InnoDB默认只有一个log group。
log group
log group实则上是一个逻辑上的概念,并没有一个实际存储的物理文件来表示log group信息。
log group由多个重做日志文件组成(其实也就是重做日志总文件),而每个log group中的日志文件大小是相同的,InnoDB对重做日志的总大小为512G.
在InnoDB中,log buffer根据一定的规则将重做日志缓冲池中的log block刷新到磁盘中,规则具体如下
- 事务提交时(可以设置提交了也不去马上重写)
- 当log buffer中有一半的空间已经被占用
- log checkpoint时(主线程进行log checkpoint)
对于log block的写入追加,是追加在redo log file的最后部分,当一个redo log file被写满时,会接者写入下一个redo log file,使用的方式为round-robin,也就是说在缓冲池里面的是log block,而刷新进磁盘里面,是刷新进redo log file,而每个log group可能有多个redo log file(默认只有1个log group)。
虽然log block总是在redo log file的最后部分进行写入,看起来是顺序的,其实并不是,因为redo log file除了保存log buffer刷新到磁盘的log block,还要保存了其他的一些信息,这些信息大概占2KB左右,而且占在redo log file的头中
即每个redo log file的前2KB部分是不保存log block信息的,主要有4部分组成
- log file header:512字节
- checkpoint1:512字节
- 空:512字节
- checkpoint2:512字节
需要注意的是,上述信息仅在每一个log group的第一个redo log file中进行存储,后面的redo log file会空出这段空间,但不会去使用其存储log block,所以导致Log group里面的redo log file并不是连续的,中间是会空出一段空间出来
而且写入新的redo log file时,还要去更新第一个redo log file前面2KB的信息(要去更新checkpoint,检查点)。
举个栗子
这是一个log group里面的栗子,里面有两个redo log file,可以看到第二条redo log file是没有接着第一条redo log file的。
重做日志格式
这里的重做日志格式是指刷新进磁盘的redo log file。
InnoDB存储引擎存储管理是基于页的,故其重做日志格式也是基于页的,但不同的数据库操作会有对应的重做日志格式,但虽然有着不同的重做日志格式,但他们有着通用的头部格式,如下所示。
可见重做日志的头部包含4个部分
- redo_log_type:重做日志的类型
- space:表空间的ID
- page_no:页的偏移量(用来记录在块里面的位置)
- redo log body:就是页里面的类容了(不属于头部),不同的数据库操作会对应不同的内容
LSN
LSN是Log Sequence Number的缩写,代表的是日志序列号,在InnoDB存储引擎中,LSN总共占用8个字节,并且是单调递增的,存在于重做日志的头部部分
LSN表示的含义有以下
- 重做日志写入的总量(单位为字节)
- checkpoint的位置
- 页的版本
LSN不仅记录在重做日志中,还存在于每个页中(前面讲数据页时,其File Header中也是有该LSN记录的,回看前面的数据页结构)。
在页中,LSN表示该页最后刷新时LSN的大小(重做日志写入的总量),重做日志组记录(log group)的是每个页(redo log file)的日志,因此页中的LSN用来判断页是否需要进行恢复操作。
举个栗子
在数据库加载数据页时,P1页的LSN为100,而InnoDB检测到写入重做日志中的LSN为1300,并且该事务是已经提交的,那么数据库就要进行一个恢复操作,将重做日志应用到P1页中,但如果P1页的LSN大于重做日志中的LSN,那么就不需要进行重做,因为P1页中的LSN表示页已经被刷新到该位置了
show engine innodb status;
可以看到日志里面总共有4个log sequenct number
- log sequence number:表示当前的LSN
- log flushed up to:表示刷新到重做日志的LSN
- pages flushed up to:表示刷新到磁盘的LSN
- Last checkpoint at:最新一次刷新进磁盘的LSN
可以看到这4个LSN是一样的,不过可能在生成环境下可能是不一样的。
恢复
InnoDB存储引擎在启动时,不管上次数据库运行时是否正常关闭,都会尝试进行恢复操作,因为重做日志记录的是物理文件,记录的是数据的存储,恢复的速度比逻辑日志(比如二进制日志,记录的是SQL语句)会快很多。
同时,InnoDB存储引擎自身也对恢复进行了一定程度的优化,比如进行顺序读取或者并行应用重做日志,这样可以进一步地提高数据库恢复的速度
通过对比Last checkpoint at和log flushed up to来进行恢复,pages flushed up to表示刷新到磁盘中的LSN,Last checkpoint at表示最新一次刷新到重做日志的LSN,那么如果这两者出现差异,就要进行恢复(pages flushed up to大于Last checkpoint at),只需要恢复LSN在Last checkpoint at和pages flushed up to的范围的重做日志即可