innodb crash
今天上午同事处理了一个innodb crash 的问题,没有备份,如何恢复?
查看日志:
180928 8:42:44 InnoDB: Error: page 163855 log sequence number 16703789459
InnoDB: is in the future! Current system log sequence number 16703705148.
InnoDB: Your database may be corrupt or you may have copied the InnoDB
根据提示信息 http://dev.mysql.com/doc/refman/5.5/en/forcing-innodb-recovery.html分析解决办法:
1:数据库系统快速关闭参数,innodb_fast_shutdown ,有3个值可以选择0,1,2
0表示在innodb关闭的时候,需要purge all, merge insert buffer,flush dirty pages。这是最慢的一种关闭方式,但是restart的时候也是最快的。
1表示在innodb关闭的时候,它不需要purge all,merge insert buffer,只需要flush dirty page,在缓冲池中的一些数据脏页会刷新到磁盘。
2表示在innodb关闭的时候,它不需要purge all,merge insert buffer,也不进行flush dirty page,只将log buffer里面的日志刷新到日志文件log files,MySQL下次启动时,会执行恢复操作
MariaDB [(none)]> show variables like '%fast%';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| innodb_fast_checksum | OFF |
| innodb_fast_shutdown | 1 |
+----------------------+-------+
不论为:0,1,2,如果存在mysql crash,其实innodb 启动过程中会利用redo log做崩溃恢复。
接下来的操作过程是
(1). Rollback uncompleted transitions 回滚为提交的事物
(2). Purge all 清除无用的undo页
(3). Merge insert buffer 合并插入缓冲
如果redolog丢失了该写入的部分数据。上述过程无法完成。系统无法正常启动。
这里官方可以move redolog来启动redolog,是有前提的:前提是 干净的关闭数据库,意味着是一致性关库,而且innodb_fast_shutdown 参数是0或1,显然不能解决上面问题
Removing redo logs to speed up recovery is not recommended, even if some data loss is acceptable.
Removing redo logs should only be considered after a clean shutdown, with innodb_fast_shutdown set to 0 or 1.
接下来使用 innodb-force-recovery 参数进行恢复:在mysql的配置文件my.cnf里找到 [mysqld]字段下,添加 innodb_force_recovery=1,如果innodb_force_recovery = 1不生效,则可尝试2——6几个数字(后面解释)
这里设置了6才能启动(why)
然后重启mysql,强制启动成功,后续恢复
1:使用mysqldump导出数据:
2:清除mysql下文件,把该参数注释掉,还原默认值0。重新初始化数据库
3:重新建库,导入数据。
配置文件的参数:innodb_force_recovery
innodb_force_recovery影响整个InnoDB存储引擎的恢复状况。默认为0,表示当需要恢复时执行所有的恢复操作(即校验数据页/purge undo/insert buffer merge/rolling back&forward),
当不能进行有效的恢复操作时,mysql有可能无法启动,并记录错误日志;
innodb_force_recovery可以设置为1-6,大的数字包含前面所有数字的影响。当设置参数值大于0后,可以对表进行select,create,drop操作,但insert,update或者delete这类操作是不允许的。
- 1(SRV_FORCE_IGNORE_CORRUPT):忽略检查到的corrupt页。
- 2(SRV_FORCE_NO_BACKGROUND):阻止主线程的运行,如主线程需要执行full purge操作,会导致crash。
- 3(SRV_FORCE_NO_TRX_UNDO):不执行事务回滚操作。
- 4(SRV_FORCE_NO_IBUF_MERGE):不执行插入缓冲的合并操作。
- 5(SRV_FORCE_NO_UNDO_LOG_SCAN):不查看重做日志,InnoDB存储引擎会将未提交的事务视为已提交。
- 6(SRV_FORCE_NO_LOG_REDO):不执行前滚的操作。
- 解释下为什么6才可以启动,因为前面看到截图,丢失redo,不能前滚,所以选择6。
-
enum { SRV_FORCE_IGNORE_CORRUPT = 1, /*!< let the server run even if it detects a corrupt page */ SRV_FORCE_NO_BACKGROUND = 2, /*!< prevent the main thread from running: if a crash would occur in purge, this prevents it */ SRV_FORCE_NO_TRX_UNDO = 3, /*!< do not run trx rollback after recovery */ SRV_FORCE_NO_IBUF_MERGE = 4, /*!< prevent also ibuf operations: if they would cause a crash, better not do them */ SRV_FORCE_NO_UNDO_LOG_SCAN = 5, /*!< do not look at undo logs when starting the database: InnoDB will treat even incomplete transactions as committed */ SRV_FORCE_NO_LOG_REDO = 6 /*!< do not do the log roll-forward in connection with recovery */ };