InnoDB Corruption

以前没有遇到InnoDB文件损坏的情况,特此记录。从日志来看,损坏的应该是一个索引页,导致对应的数据表无法访问,也无法获取对应数据表中的数据,尝试check optimize也无法修复。最后设置innodb_force_recovery=1后启动数据库后,能够导出全部数据。

1. 故障

最近,在从一个Xtrabackup的备份中恢复数据后,发现MySQL数据库能正常启动,但是发现use dbname一下MySQL就会崩溃,看日志:

InnoDB: Database page corruption on disk or a failed
InnoDB: file read of page 4.
InnoDB: You may have to recover from a backup.
100505 10:19:07 InnoDB: Page dump in ascii and hex (16384 bytes):
len 16384; hex 89ecae1d00000004ffffffffffffffff0000014bf7119c4545
……
……
100505 10:19:07 InnoDB: Page checksum 2313989661, prior-to-4.0.14-form checksum 3285785245
InnoDB: stored checksum 2313989661, prior-to-4.0.14-form stored checksum 1519970954
InnoDB: Page lsn 331 4145126469, low 4 bytes of lsn at page end 1983060
InnoDB: Page number (if stored to page already) 4,
InnoDB: space id (if created with >= MySQL-4.1.1 and stored already) 884
InnoDB: Page may be an index page where index id is 0 1929
InnoDB: (index “IDX_fa_login_userid” of table “fa”.”login_history_0015″)
InnoDB: Database page corruption on disk or a failed
InnoDB: file read of page 4.

从上面的信息我们看到,可能是表”fa”.”login_history_0015″的索引页有损坏。虽然这个表故障了,不过MySQL还是能够正常启动,而且对其他表也是能够正常操作的。需要注意的是,用mysql client连接进去时需要使用参数-A,否则use dbname的时候可能会有问题。

$mysql -uroot -A -p

2. check修复

根据Eerror Log中的提示使用CHECK TABLE修复:

root@fa 10:28:14>check table login_history_0015;
ERROR 2013 (HY000): Lost connection to MySQL server during query
root@fa 10:28:49>100505 10:28:49 mysqld_safe Number of processes running now: 0
100505 10:28:49 mysqld_safe mysqld restarted

未果!

2. OPTIMIZE修复

尝试OPTIMIZE TABLE

root@fa 10:35:30> OPTIMIZE TABLE login_history_0015;
ERROR 2013 (HY000): Lost connection to MySQL server during query

未果

3. 尝试innodb_force_recovery

在my.cnf中设置innodb_force_recovery=1,该参数使得InnoDB即使检测到corrupt page仍然启动MySQL,并将InnoDB置于只读状态:

InnoDB: innodb_force_recovery is on: we do not allow
InnoDB: database modifications by the user. Shut down

OK,发现这样可以访问数据表,虽然无法修改数据表。但是这就足够了,这样就可以用msyqldump导出全部的数据了。

4. 故障原因

因为是数据是从备库中恢复过来的,先怀疑是不是这台主机有问题(恢复的时候磁盘出现某个莫名的故障),换了一台主机恢复,故障依旧。这说明是这个备份文件是有问题的。

于是从同一台主机上前一天的Xtrabackup中恢复,没有遇到故障;后来第二天,我又在主机上做了一个Xtrabackup备份,再恢复,问题没有重现。这说明只有那一天的Xtrabackup有故障。

无法定位原因。

因为是从备份中恢复的数据,检查了一下主库上这个表是正常,所以认为是备份的时候出现的故障,猜测:备份是用Xtrabackup做的,有可能是Xtrabackup的Bug(用前一天Xtrabackup再做了一次恢复,并没有出现类似的问题),也可能是备份的时候想NAS写的时候出现“意外”……

谁知道呢

参考文献:
[1]. Recovering Innodb table Corruption
[2]. Forcing InnoDB Recovery

In:

One response to “InnoDB Corruption”

  1. 总感觉mysql/innodb 过于依赖于mysql这个前端接口,做个recovery都得由“mysqld启动”这个事件来触发,挺麻烦的

Leave a Reply

Your email address will not be published. Required fields are marked *