0%

记录-Mysql无法启动及数据恢复

Pre:

Centos7又报io error了.

然后想着把数据库的数据迁移出来.

用Navicat直接操作的时候,发现一直报连接不了数据库的错误.无法正常使用.

然后上头说尝试恢复下硬盘.


修复硬盘:

按这个链接Centos 7 LVM xfs文件系统修复尝试了一下,未果.

因为上次是进不去系统才进行了xfs_repair,这次一断电才开机就又正常了.

然后以为机器正常了,可是这个时候mysql的服务起不来了.

这个时候没有看mysql的状态和log.不好的习惯.

那只好尝试一下通过文件来迁移数据库Mysql.


通过文件迁移数据库:

按照【MySQL】MySQL数据库迁移并同步(简单粗暴版) 来传mysql的文件.

里面提到通过用rsync来传文件.

1
2
3
4
#后面的路径是目标路径
rsync -avz /var/lib/mysql 192.168.189.131:/var/lib/mysql

rsync -avz /var/lib/mysql 192.168.189.131:/var/lib/

具体用的哪条命令,忘了…


查看Log

迁移完数据库文件后,重启数据库服务,依旧起不来.

发现状态一直在activating

根据Centos7 上安装mysql遇上的问题:mysql无法正常启动,去看mysql的log.

才找到了问题所在.

看Log的重要性!!!

看Log的重要性!!!

看Log的重要性!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
InnoDB: Error: trying to access page number 0 in space 168,
InnoDB: space name okcloud/ok_1_ipscan_task_result,
InnoDB: which is outside the tablespace bounds.
InnoDB: Byte offset 0, len 16384, i/o type 10.
InnoDB: If you get this error at mysqld startup, please check that
InnoDB: your my.cnf matches the ibdata files that you have in the
InnoDB: MySQL server.
2019-07-29 19:23:43 7f2a7946d700 InnoDB: Assertion failure in thread 139820400039680 in file fil0fil.cc line 5666
InnoDB: We intentionally generate a memory trap.
InnoDB: Submit a detailed bug report to http://bugs.mysql.com.
InnoDB: If you get repeated assertion failures or crashes, even
InnoDB: immediately after the mysqld startup, there may be
InnoDB: corruption in the InnoDB tablespace. Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.6/en/forcing-innodb-recovery.html
InnoDB: about forcing recovery.

访问这个表ok_1_ipscan_task_result出错,可参考forcing recovery


恢复数据:

Mysql Forcing InnoDB Recovery特性:

需要做特殊操作,让 MySQL 跳过恢复,启动 MySQL,然后把数据导出来,再重建数据库导入。

MySQL 有个一个特性:Forcing InnoDB Recovery,启用这个特性需要设置

innodb_force_recovery 大于 0。

innodb_force_recovery 可以设置为 1-6,大的值包含前面所有小于它的值的影响。

  1. (SRV_FORCE_IGNORE_CORRUPT): 忽略检查到的 corrupt 页。尽管检测到了损坏的 page 仍强制服务运行。一般设置为该值即可,然后 dump 出库表进行重建。

  2. (SRV_FORCE_NO_BACKGROUND): 阻止主线程的运行,如主线程需要执行 full purge 操作,会导致 crash。 阻止 master thread 和任何 purge thread 运行。若 crash 发生在 purge 环节则使用该值。

  3. (SRV_FORCE_NO_TRX_UNDO): 不执行事务回滚操作。

  4. (SRV_FORCE_NO_IBUF_MERGE): 不执行插入缓冲的合并操作。如果可能导致崩溃则不要做这些操作。不要进行统计操作。该值可能永久损坏数据文件。若使用了该值,则将来要删除和重建辅助索引。

  5. (SRV_FORCE_NO_UNDO_LOG_SCAN): 不查看重做日志,InnoDB 存储引擎会将未提交的事务视为已提交。此时 InnoDB 甚至把未完成的事务按照提交处理。该值可能永久性的损坏数据文件。

  6. (SRV_FORCE_NO_LOG_REDO): 不执行前滚的操作。恢复时不做 redo log roll-forward。使数据库页处于废止状态,继而可能引起 B 树或者其他数据库结构更多的损坏。

一般设为1即可,当时没认真看,直接设为了6…

6可能损坏原有数据库表…


做法:

1
2
3
4
my.cnf 中添加:

[mysqld]
innodb_force_recovery = 1

然后重启数据库,用Navicat将数据库转储成sql语句.

只有在mysql log里报错误的那个表导不出来.不过已经足够了.

恢复了很多的数据.


Refs: