经常接触数据库的难免遇到数据库崩溃的问题,另外发现使用windows的,遇到的几率会高点。
- 问题描述,mysql/mariadb突然就不能访问了,然后也无法启动,查看数据库日志,报些莫名奇妙的错误。
[ERROR] mysqld got exception 0x80000003 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.To report this bug, see https://mariadb.com/kb/en/reporting-bugs
- 如果有备份(比如热备,binlog等),则直接恢复。本文针对的不是这类场景。
- 更多时候没有备份,或者测试环境,可以使用强制innodb恢复的方法。下面的内容摘录翻译自官方mysql文档, 英文可以的可以直接移步到官网。
3.1 一切开始之前,先备份物理文件,如mysql的data目录,以防损坏时可以恢复。
3.2 修改mysql的配置文件,mysql.ini中的 innodb_force_recovery
选项,该选项可取 0-6
innodb_force_recovery允许的非零取值范围为1到6,取值越大包含了较小值的功能。例如,取值为3包含了取值为1和2的所有功能。
如果在innodb_force_recovery值为3或更小的情况下能够成功导出表格数据,那么相对来说只有一些存在损坏的页面上的数据丢失。取值为4或更大的情况被认为是危险的,因为数据文件可能会被永久损坏。取值为6被认为是极端的,因为数据库页面会处于过时状态,这可能会对B树和其他数据库结构引入更多的损坏。因此尝试时需要从1开始,尝试是否可以启动数据库,如果不能启动慢慢加大此值,直到可以启动数据库。
- 0:默认值(不启用强制恢复),也就是平时正常运行时的配置;
- 1:(SRV_FORCE_IGNORE_CORRUPT)当检测到损坏页面时,允许服务器继续运行;
- 2:(SRV_FORCE_NO_BACKGROUND)阻止主线程和任何清理线程的运行。如果在清理操作期间出现意外退出,这个恢复级别可以预防;
- 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)在恢复过程中不执行重做日志的向前回滚操作;
3.3 启动数据库后就可以借助mysqldump工具,或者数据库管理软件导出自己的库表数据。
3.4 如果知道是那个表导致的崩溃,同时上面的值小于4时,则可以尝试删除该表,并从上面的导出的数据进行恢复该表。(如果不知道那个表损坏则移步3.6)
3.5 修改上面的innodb_force_recovery
选项,注释掉,同时也恢复其值为默认值。 然后重启数据库,看看是否可用。
3.6 如果不确定是那个表导致的问题,则直接可以删除mysql的数据目录(注意,此操作会删除数据库的用户,因此也要根据情形选择是否需要备份),然后修改上面的innodb_force_recovery
选项,注释掉,同时也恢复其值为默认值。 重启数据库后导入上面导出的数据,并创建用户及权限。