18
2021
01
16:57:10

一次服务器断电,造成innodb引擎表(日志表)损坏的解决办法

1、mysql日志报错

innodb引擎提示数据库没有正常关闭,报innodb错误

180112  0:49:28  InnoDB: Database was not shut down normally!InnoDB: Starting crash recovery.
InnoDB: Reading tablespace information from the .ibd files...
InnoDB: Restoring possible half-written data pages from the doublewrite
InnoDB: buffer...
InnoDB: Doing recovery: scanned up to log sequence number 2580576839
180112  0:49:28  InnoDB: Error: page 1 log sequence number 2580582651
InnoDB: is in the future! Current system log sequence number 2580576839.
InnoDB: Your database may be corrupt or you may have copied the InnoDB
InnoDB: tablespace but not the InnoDB log files. See
InnoDB: http://dev.mysql.com/doc/refman/5.5/en/forcing-innodb-recovery.html
InnoDB: for more information.
180112  0:49:28  InnoDB: Error: page 5 log sequence number 2580579963
InnoDB: is in the future! Current system log sequence number 2580576839.
InnoDB: Your database may be corrupt or you may have copied the InnoDB
InnoDB: tablespace but not the InnoDB log files. See
InnoDB: http://dev.mysql.com/doc/refman/5.5/en/forcing-innodb-recovery.html
InnoDB: for more information.
180112  0:49:29  InnoDB: Error: page 65565 log sequence number 2580577006
InnoDB: is in the future! Current system log sequence number 2580576839.
InnoDB: Your database may be corrupt or you may have copied the InnoDB
InnoDB: tablespace but not the InnoDB log files. See
InnoDB: http://dev.mysql.com/doc/refman/5.5/en/forcing-innodb-recovery.html
InnoDB: for more information.
180112  0:49:29  InnoDB: Error: page 65566 log sequence number 2580577176
InnoDB: is in the future! Current system log sequence number 2580576839.
InnoDB: Your database may be corrupt or you may have copied the InnoDB
InnoDB: tablespace but not the InnoDB log files. See
InnoDB: http://dev.mysql.com/doc/refman/5.5/en/forcing-innodb-recovery.html
InnoDB: for more information.
180112  0:49:29  InnoDB: Starting an apply batch of log records to the database...
InnoDB:
 Progress in percents: 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 180112  
0:49:29  InnoDB: Assertion failure in thread 140330795001600 in file rem0rec.c line 569
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.5/en/forcing-innodb-recovery.html
InnoDB: about forcing recovery.
16:49:29 UTC - mysqld got signal 6 ;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.
We will try our best to scrape up some info that will hopefully helpdiagnose the problem, but since we have already crashed, 
something is definitely wrong and this may fail.


2、查看mysql服务状态,提示mysql没在运行,但是锁定文件存在

ERROR! MySQL is not running,but lock file (/var/lock/subsys/mysql) exists


3、重启mysql服务,提示错误

[root@mail subsys]# /etc/init.d/umail_mysqld restart
 ERROR! MySQL server PID file could not be found!Starting MySQL. ERROR! The server quit without updating PID file (/usr/local/u-mail/data/mysql/default.pid).

日志报下面的错误:

180112  9:12:44 InnoDB: Cannot initialize created log files because
180112  9:12:44 InnoDB: data files are corrupt, or new data files were
180112  9:12:44 InnoDB: created when the database was started previous
180112  9:12:44 InnoDB: time but the database was not shut down
180112  9:12:44 InnoDB: normally after that.
180112  9:12:44 [ERROR] Plugin 'InnoDB' init function returned error.
180112  9:12:44 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.

将数据库下ib_logfile文件移动走后(因为最开始看日志的时候提示了InnoDB: tablespace but not the InnoDB log files. See ),可以重启mysql服务。


4、以为重启mysql成功后就可以,但是没想到innodb引擎表已经损坏了。

日志提示:

180112  9:37:40 [ERROR] Cannot find or open table umail/core_auth_log from
the internal data dictionary of InnoDB though the .frm file for the
table exists. Maybe you have deleted and recreated InnoDB data
files but have forgotten to delete the corresponding .frm files
of InnoDB tables, or you have moved .frm files to another database?
or, the table contains indexes that this version of the engine
doesn't support.
See http://dev.mysql.com/doc/refman/5.5/en/innodb-troubleshooting.html
how you can resolve the problem

(1)用phpmyadmin进去看提示正在使用,修复提示Unknown storage engine 'InnoDB '错误。

(2)mysql命令控制台输入show engines;查看,也没有innodb引擎。


5、解决办法(数据会丢失,除非有备份数据)

(1)将ib开头的日志文件和数据文件移动走(最好停止umail后移动走,然后再开启umail)

(2)使用drop tables 表名;,删除innodb表

(3)停止与mysql服务相关的服务

(4)使用show processlist;命令查看是否有锁定
(5)将创建这几个表的sql文件放在一个路径下
(6)到mysql命令控制台输入source /usr/local/kx-mail/data/mysql/default/base_table.sql导入表结构
(7)重启mysql服务


6、总结(平时数据库要用mysqldump最好备份,也可以单独对表做备份,出现问题的时候还原)

ibdata1文件很多,将近2GB(innodb_file_per_table参数可以给ibdata文件瘦身)。可能和这个文件太大,而且又突然断电有关系。

分析日志后发现,数据库无法重启的原因是因为ibdata1文件损坏,重启后无法正常恢复。

解决办法:
需要跳过恢复步骤,修改my.cnf文件,在my.cnf中的[mysqld]中添加:
innodb_force_recovery = 6
innodb_purge_threads = 1

解释:
innodb_force_recovery可以设置为1-6,大的数字包含前面所有数字的影响。
具体数字对应的含义:
1-----(SRVFORCEIGNORECORRUPT):忽略检查到的corrupt页。
2-----(SRVFORCENOBACKGROUND):阻止主线程的运行,如主线程需要执行full purge操作,会导致crash。
3-----(SRVFORCENOTRXUNDO):不执行事务回滚操作。
4-----(SRVFORCENOIBUFMERGE):不执行插入缓冲的合并操作。
5-----(SRVFORCENOUNDOLOGSCAN):不查看重做日志,InnoDB存储引擎会将未提交的事务视为已提交。
6-----(SRVFORCENOLOG_REDO):不执行前滚的操作。

再次启动mysql就ok了.
如果还无法启动,则需要删除数据目录datafile下的 ibdata1,ib_logfile*等文件。然后恢复数据库信息(本次用的方法)


以下内容转自:http://blog.csdn.net/hzqhbc/article/details/21465983
MySQL数据库INNODB 表损坏修复处理过程


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

处理过程:
 一遇到报警之后,直接打开错误日志,里面的信息:

InnoDB: Database page corruption on disk or a failed
InnoDB: 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 3765017239
InnoDB: stored checksum 3904709694, prior-to-4.0.14-form stored checksum 3765017239
InnoDB: Page lsn 5 614270220, low 4 bytes of lsn at page end 614270220
InnoDB: Page number (if stored to page already) 30506,
InnoDB: space id (if created with >= MySQL-4.1.1 and stored already) 19
InnoDB: Page may be an index page where index id is 54
InnoDB: (index "PRIMARY" of table "maitem"."email_status")
InnoDB: Database page corruption on disk or a failed
InnoDB: file read of page 30506.
InnoDB: You may have to recover from a backup.
InnoDB: It is also possible that your operating
InnoDB: system has corrupted its own file cache
InnoDB: and rebooting your computer removes the
InnoDB: error.
InnoDB: If the corrupt page is an index page
InnoDB: you can also try to fix the corruption
InnoDB: by dumping, dropping, and reimporting
InnoDB: the corrupt table. You can use CHECK
InnoDB: TABLE to scan your table for corruption.
InnoDB: See also http://dev.mysql.com/doc/refman/5.5/en/forcing-innodb-recovery.html
InnoDB: about forcing recovery.
InnoDB: A new raw disk partition was initialized or
InnoDB: innodb_force_recovery is on: we do not allow
InnoDB: database modifications by the user. Shut down
InnoDB: mysqld and edit my.cnf so that newraw is replaced
InnoDB: 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_force_recovery影响整个InnoDB存储引擎的恢复状况。默认为0,表示当需要恢复时执行所有的

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):不执行前滚的操作。

因为错误日志里面提示出现了坏页,导致数据库崩溃,所以这里把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 =1。
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回来。




推荐本站淘宝优惠价购买喜欢的宝贝:

image.png

本文链接:https://hqyman.cn/post/1607.html 非本站原创文章欢迎转载,原创文章需保留本站地址!

分享到:
打赏





休息一下~~


« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

请先 登录 再评论,若不是会员请先 注册

您的IP地址是: