总体来说,innodb恢复过程包含以下几个步骤:
一、查找表空间:
这里的查找表空间,主要是查找重做日志来实现的。
如果innodb发现到上一次检查点之后写入的重做日志,那么必须将重做日志应用于受影响的表空间。在恢复期间标记受影响的表空间。
通过将重做日志从最后一个检查点扫描到日志末尾来执行查找表空间,以查找在 MLOG_FILE_NAME
修改表空间页时写入的记录。一个 MLOG_FILE_NAME
记录包含表空间的space ID和文件名。
启动时,InnoDB
打开系统表空间和重做日志。如果自上一个检查点以来写入了重做日志记录,则会根据MLOG_FILE_NAME
记录打开受影响的表空间文件。
MLOG_FILE_NAME
里包括每表文件表空间,通用表空间,系统表空间和撤消日志表空间。space id和路径。
在发现重做日志时:
1、会只访问自上次check point以来的表空间文件,指受影响的表等,将影响降到最低。
2、在应用重做日志时,会忽略受影响的表上未涉及的文件。锁定粒度更小。
3、检查到MLOG_FILE_NAME如果不匹配,那么会恢复失败。失败原因可能是检查到多个MLOG_FILE_NAME。零或一个不会失败。
4、如果innodb检查到缺少了表空间文件,则也会失败。
具体过程:
1、初始化内存对象。
查找第一个LSN,从双写缓冲恢复第一个PAGE
2、扫描三次redo日志:
(1)扫描MLOG_CHECKPOINT找到CHECKPOINT LSN
(2)再从检查点开始扫描,找到MLOG_FILE_NAME里的存储对象
(3)检查hash空间大小,如果不足,则恢复完后清空再恢复一批。
简而言之,第一次扫描找到正确的MLOG_CHECKPOINT位置;第二次扫描解析 redo 日志并存储到hash中;如果hash空间不够用,则再来一轮重新开始,解析一批,应用一批。
3、如果binlog打开,进行XA恢复:
(1)首先扫描最后一个binlog文件,找到其中所有的XID事件,并将其中的XID记录到一个hash结构中
(2)拿到每个事务引擎中处于prepare状态的事务xid,如果这个xid存在于binlog中,则提交;否则回滚事务。
二、重做日志应用:
如果在崩溃时已经将所有数据刷新到硬盘,那么会跳过恢复程序直接启动。如果缺少重做日志文件,那么innodb也会直接跳过。
三、回滚未完成的事物:
是指在崩溃时,还处于活动的事物,从双写缓冲恢复,通常会花费三到四倍的时间,具体取决于服务器负载。
四、更改缓冲区合并:
将更改缓冲区的更改应用于 二级索引的页上,因为索引页将读取到缓冲池。
五、清除:
删除活动事务不再可见的删除标记记录。
在第二步骤之后,就不再依赖重做日志进行恢复了。
如果无法启动,使用 innodb_force_recovery参数进行启动恢复。