InnoDB crash recovery 过程和疑问

2020-07-13  本文已影响0人  轻松的鱼

参考资料

相关知识点

LSN

checkpoint

逻辑流程

  1. 当正常 shutdown 实例时,会将所有的脏页都刷到磁盘,并做一次完全同步的 checkpoint;同时将最后的 lsn 写到系统表 ibdata 的第一个 page 中(函数fil_write_flushed_lsn)。在重启时,可以根据该lsn来判断这是不是一次正常的 shutdown,如果不是就需要去做崩溃恢复逻辑;

  2. 表空间发现
    即找到从 last checkpoint LSN 后做过修改的表空间文件,避免打开所有的表空间。是通过 MLOG_FILE_NAME 来实现的:在一次 checkpoint 后第一次修改某个表的数据时,总是先写一条 MLOG_FILE_NAME 日志,记录 space ID 和文件名。

  3. 应用 redo log
    打开上一步得到的表空间,依次将 page 读入内存;从 redo log file 中获取 last checkpoint LSN,应用所有大于这个 LSN 的 redo log(只有LSN大于数据页上LSN的日志才会被应用)

  4. 遍历每个回滚段的 insert_undo_list 与update_undo_list,取出的undo,根据undo日志信息,重建事务;并且根据事务的不同状态:
    a. undo 事务状态为TRX_UNDO_ACTIVE,为活跃事务,TRX_ACTIVE
    b. undo 事务状态为TRX_UNDO_PREPARED -> TRX_PREPARED

  5. 回滚处于 ACTIVE 状态的 DDL、DML 事务。而处于 PREPARE 状态的事务需要与 binlog 结合判断:
    a. 如果这个事务已经持久化到 binlog 中,即有 XID event,则不需要回滚这个事务
    b. 如果没有持久化到 binlog 中,则回滚

案例

分析一个 crash recovery 失败的异常案例:MySQL意外关闭,之后误删除 redo log,启动报错:

2020-05-28T10:35:26.800467+08:00 0 [Note] InnoDB: Log scan progressed past the checkpoint lsn 2437132
2020-05-28T10:35:26.800498+08:00 0 [Note] InnoDB: Doing recovery: scanned up to log sequence number 2437160
2020-05-28T10:09:06.785759+08:00 0 [Note] InnoDB: Starting crash recovery.
2020-05-28T10:09:06.809837+08:00 0 [ERROR] InnoDB: Page [page id: space=0, page number=7] log sequence number 8403155287 is in the future! Current system log sequence number 2437150.
2020-05-28T10:09:06.809917+08:00 0 [ERROR] InnoDB: Your database may be corrupt or you may have copied the InnoDB tablespace but not the InnoDB log files. Please refer to http://dev.mysql.com/doc/refman/5.7/en/forcing-innodb-recovery.html for information about forcing recovery.
2020-05-28T10:09:06.811243+08:00 0 [ERROR] InnoDB: Page [page id: space=0, page number=4] log sequence number 8405956349 is in the future! Current system log sequence number 2437150.

原因:

疑问

关于 innodb_force_recovery=3 和 5 的区别在哪里?
上一篇 下一篇

猜你喜欢

热点阅读