在《redo Log 格式浅析》文章中,我们介绍了redo log的基本格式和结构以及写入步骤。数据库系统与文件系统的最大的区别就是要最大限度的保证操作的原子性,在InnoDB存储引擎中就是依靠redo log来保证的。当数据库异常崩溃后,数据库重新启动时会根据redo log进行数据恢复,保证数据库恢复到崩溃前的状态。那么这个过程在InnoDB里面是如何进行的呢,本文将结合MySQL 8.0.12的源代码进行简要的解析。1. InnoDB崩溃恢复相关参数在介绍MySQL InnoDB崩溃恢复流程之前,先简单介绍一下与它有关的几个重要参数。
Innodb_fast_shutdown: 在mysql关闭时,参数innodb_fast_shutdown 影响着存储引擎innodb的行为。参数为0,1,2三个值。0,代表当MYSQL关闭时,Innodb需要完成所有full purge和merge insert buffer操作,这需要花费时间来完成。
1,是参数的默认值,不需要完成full purge和merge insert buffer操作,但是在缓冲池的一些数据脏页还是会刷新到磁盘。
2,表示不需要完成full purge和merge insert buffer操作 ,也不将缓冲池中的数据脏页写回磁盘,而是将日志都写入日志文件。这样不会有任何事务丢失,但是MySQL在下次启动时,会执行恢复操作(recovery)。
innodb_force_recovery: 影响了整个Innodb存储引擎的恢复状况。该值默认为0,表示当需要恢复时执行所有的恢复操作。当不能进行有效恢复时(如数据页发生了corruption,InnoDB引擎可能会无法启动)把错误写入错误日志中。
Innodb_force_recovery可以设置6个非零值:(SRV_FORCE_IGNORE_CORRUPT):忽略检查到的corrupt页。
(SRV_FORCE_NO_BACKGROUND):阻止主线程的运行,如主线程需要执行full purge操作,会导致crash。
(SRV_FORCE_NO_TRX_UNDO):不执行事务回滚操作.
(SRV_FORCE_NO_IBUF_MERGE):不执行插入缓冲的合并操作.
(SRV_FORCE_NO_UNDO_LOG_SCAN):不查看重做日志,InnoDB存储引擎会将未提交的事务视为已提交。
(SRV_FORCE_NO_LOG_REDO):不执行前滚的操作。2. 与崩溃恢复相关的重要数据结构log_t :该结构体的定义在storage/innobase/include/log0types.h中。InnoDB系系运行时刻只会有一个该数据结构的实例log_sys,log_sys的定义在strorage/innobase/log0log.cc中(log_t *log_sys) 。 log_sys中存储了innodb redo log系统运行时刻的各种状态。
recv_sys_t : 该结构体的定义在/storage/innobase/include/log0recv.h中。这个结构体变量用来描述恢复系统运行时刻的状态。InnoDB运行时刻有一个该数据结构的实例recv_sys,recv_sys的定义在storage/innobase/log/log0recv.cc中