您的当前位置:首页正文

MySQL数据库INNODB表损坏修复处理过程分享

2020-06-14 来源:独旅网
MySQL数据库INNODB表损坏修复处理过程分享

突然收到MySQL报警,从库的数据库挂了,⼀直在不停的重启,打开错误⽇志,发现有张表坏了。innodb表损坏不能通过repair table 等修复myisam的命令操作。现在记录下解决过程,下次遇到就不会这么⼿忙脚乱了。

⼀遇到报警之后,直接打开错误⽇志,⾥⾯的信息:

InnoDB: Database page corruption on disk or a failedInnoDB: file read of page 30506.

InnoDB: You may have to recover from a backup.

130509 20:33:48 InnoDB: Page dump in ascii and hex (16384 bytes):##很多⼗六进制的代码…………

InnoDB: End of page dump

130509 20:37:34 InnoDB: Page checksum 1958578898, prior-to-4.0.14-form checksum 3765017239InnoDB: stored checksum 3904709694, prior-to-4.0.14-form stored checksum 3765017239InnoDB: Page lsn 5 614270220, low 4 bytes of lsn at page end 614270220InnoDB: Page number (if stored to page already) 30506,

InnoDB: space id (if created with >= MySQL-4.1.1 and stored already) 19InnoDB: Page may be an index page where index id is 54InnoDB: (index \"PRIMARY\" of table \"maitem\".\"email_status\")InnoDB: Database page corruption on disk or a failedInnoDB: file read of page 30506.

InnoDB: You may have to recover from a backup.InnoDB: It is also possible that your operatingInnoDB: system has corrupted its own file cacheInnoDB: and rebooting your computer removes theInnoDB: error.

InnoDB: If the corrupt page is an index pageInnoDB: you can also try to fix the corruptionInnoDB: by dumping, dropping, and reimportingInnoDB: the corrupt table. You can use CHECKInnoDB: TABLE to scan your table for corruption.

InnoDB: See also http://dev.mysql.com/doc/refman/5.5/en/forcing-innodb-recovery.htmlInnoDB: about forcing recovery.

InnoDB: A new raw disk partition was initialized orInnoDB: innodb_force_recovery is on: we do not allowInnoDB: database modifications by the user. Shut downInnoDB: mysqld and edit my.cnf so that newraw is replacedInnoDB: with raw, and innodb_force_... is removed.

130509 20:39:35 [Warning] Invalid (old?) table or database name '#sql2-19c4-5'

从错误⽇志⾥⾯很清楚的知道哪⾥出现了问题,该怎么处理。这时候数据库隔⼏s就重启,所以差不多可以说你是访问不了数据库的。所以马上想到要修复innodb表了。

以前在Performance的blog上看过类似⽂章。

当时想到的是在修复之前保证数据库正常,不是这么异常的⽆休⽌的重启。所以就修改了配置⽂件的⼀个参数:

innodb_force_recovery影响整个InnoDB存储引擎的恢复状况。默认为0,表⽰当需要恢复时执⾏所有的

innodb_force_recovery可以设置为1-6,⼤的数字包含前⾯所有数字的影响。当设置参数值⼤于0后,可以对表进⾏select,create,drop操作,但insert,update或者delete这类操作是不允许的。

因为错误⽇志⾥⾯提⽰出现了坏页,导致数据库崩溃,所以这⾥把innodb_force_recovery 设置为1,忽略检查到的坏页。重启数据库之后,正常了,没有出现上⾯的错误信息。找到错误信息出现的表:(index \"PRIMARY\" of table \"maitem\".\"email_status\")

数据页⾯的主键索引(clustered key index)被损坏。这种情况和数据的⼆级索引(secondary indexes)被损坏相⽐要糟很多,因为后者可以通过使⽤OPTIMIZE TABLE命令来修复,但这和更难以恢复的表格⽬录(table dictionary)被破坏的情况来说要好⼀些。因为被破坏的地⽅只在索引的部分,所以当使⽤innodb_force_recovery = 1运⾏InnoDB时,操作如下:

执⾏check,repair table 都⽆效

alter table email_status engine =myisam; #也报错了,因为模式是innodb_force_recovery =。ERROR 1025 (HY000): Error on rename of '...' to '....' (errno: -1)

create table email_status_bak #和原表结构⼀样,只是把INNODB改成了MYISAM。insert into email_status_bak select * from email_status;删除掉原表:

drop table email_status;

注释掉innodb_force_recovery 之后,重启。重命名:

rename table edm_email_status_bak to email_status;最后该回存储引擎

alter table edm_email_status engine = innodb

这⾥的⼀个重要知识点就是 对 innodb_force_recovery 参数的理解了,要是遇到数据损坏甚⾄是其他的损坏。可能上⾯的⽅法不⾏了,需要尝试另⼀个⽅法:insert into tb select * from ta limit X;甚⾄是dump出去,再load回来。

因篇幅问题不能全部显示,请点此查看更多更全内容