阿里云快照回滚后 MySQL 无法启动

问题

阿里云快照回滚后 MySQL 启动时报错,无法正常启动 MySQL。

解决

好在 MySQL 的日志给出了解决方法:set innodb_force_recovery=1。于是,修改配置文件 vim /etc/my.cnf,在最后增加一行:innodb_force_recovery=1,保存,然后重启服务器。

MySQL 启动成功,但是在处理业务时依旧报错。

继续查看 MySQL 日志,原来把 innodb_force_recovery 设置为 1 后,MySQL 就不允许修改数据了,需要把 innodb_force_recovery 重新设置为 0,根据提示修改 innodb_force_recovery=0

重启 MySQL 成功,业务也能正常进行了。

原理

MySQL 的 innodb_force_recovery 参数,说明如下:

这个参数是当 MySQL 奔溃导致数据库表空间损坏,或者其他原因导致 innodb 事务日志损坏,最终导致 MySQL 闪退后无法正常启动时使用的。这个参数的默认值是 0, 如果面临上述问题,无法正常启动 MySQL , 并且查看 MySQL 错误日志,发现导致 MySQL 无法启动的原因是 innodb ,那么就需要设置这个参数了。

它的取值范围是 0-6,含义如下:

  • (SRV_FORCE_IGNORE_CORRUPT): 忽略检查到的 corrupt 页。尽管检测到了损坏的 page 仍强制服务运行。一般设置为该值即可,然后 dump 出库表进行重建。
  • (SRV_FORCE_NO_BACKGROUND): 阻止主线程的运行,如主线程需要执行 full purge 操作,会导致 crash。 阻止 master thread 和任何 purge thread 运行。若 crash 发生在 purge 环节则使用该值。
  • (SRV_FORCE_NO_TRX_UNDO): 不执行事务回滚操作。
  • (SRV_FORCE_NO_IBUF_MERGE): 不执行插入缓冲的合并操作。如果可能导致崩溃则不要做这些操作。不要进行统计操作。该值可能永久损坏数据文件。若使用了该值,则将来要删除和重建辅助索引。
  • (SRV_FORCE_NO_UNDO_LOG_SCAN): 不查看重做日志,InnoDB 存储引擎会将未提交的事务视为已提交。此时 InnoDB 甚至把未完成的事务按照提交处理。该值可能永久性的损坏数据文件。
  • (SRV_FORCE_NO_LOG_REDO): 不执行前滚的操作。恢复时不做 redo log roll-forward。使数据库页处于废止状态,继而可能引起 B 树或者其他数据库结构更多的损坏。

使用参数 innodb_force_recovery 建议:

  • 如果 MySQL 服务故障重启后,因为事务回滚导致异常,可以将参数 innodb_force_recovery 设置为 3 跳过回滚阶段
  • 如果因为 MySQL 数据页损坏导致异常,可以使用 SELECT+WHERE 查找出未损坏数据并将其通过 mysqldump 导出。
  • 将 innodb_force_recovery 参数设置大于 0 启动服务后,应通过修改端口或域名 (VIP) 指向来屏蔽应用访问。
  • 将 innodb_force_recovery 参数设置大于 0 启动服务后,可以通过 mysqlcheck 命令来对表进行检查 / 分析 / 优化 / 修复。
  • 使用 force_recovery 重启服务前,建议对数据库所有文件进行备份,避免修复过程中对数据进行二次损害。

小结

阿里云快照在生成的时候会破坏本地数据库的完整性,应当使用更为优雅的备份方案(比如:使用独立的数据库服务器)。

数据库出现异常时,查看日志是解决问题的第一步,通过日志能解决大部分的问题。


参考文章: [1] guotianqing . Mysql历险记 . CSDN . 2021-05-08

全部评论(0)
必填
必填,不公开
我信任你,不会填写广告链接
收起