mysql innodb表修复_Mysql INNODB存储引擎表损坏修复方法(转)

设你正在运行使用InnoDB表格的MySQL,糟糕的硬件设备,驱动程序错误,内核错误,不幸的电源故障或某些罕见的MySQL错误使你的InnoDB表空间被损坏了。

在这种情况下,InnoDB的一般会出现这样的输出:

InnoDB: Database page corruption on disk ora failed

InnoDB: file read of page 7.

InnoDB: You may have to recover from a backup.

080703 23:46:16 InnoDB: Page dump in ascii and hex (16384bytes):

… 这里省略很多二进制和十六进制编码…

080703 23:46:16 InnoDB: Page checksum 587461377,prior-to-4.0.14-form checksum 772331632

InnoDB: stored checksum 2287785129, prior-to-4.0.14-form storedchecksum 772331632

InnoDB: Page lsn 24 1487506025, low 4 bytes of lsn at page end1487506025

InnoDB: Page number (if stored to page already) 7,

InnoDB: Database page corruption on disk or a failed

mysqldump导出库时报错如下:

“mysqldump: Error 2013: Lost connection to MySQL server during query when dumping table `; at row:6880″

或是操作对应表时,也会报错。这时数据库会重启。

当时想到的是在修复之前保证数据库正常,不是这么异常的无休止的重启。

使用innodb_force_recovery =1,正如你所看到的,即使日志文件中有校验失败的记录,但CHECK TABLE还是说表格是正确的。

这意味着你不能太依赖CHECKTABLE在InnoDB上执行的结果。

所以就修改了配置文件的一个参数: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,忽略检查到的坏页。

重启数据库之后,找到错误信息出现的表

因为后者可以通过使用OPTIMIZE TABLE命令来修复,但这和更难以恢复的表格目录(table dictionary)被破坏的情况来说要好一些。

操作步骤:

修改my.cnf 配置文件,添加innodb_force_recovery = 1运行InnoDB,然后重启mysql 。

1,建议一个备份表,T_MinuteStore_BAK,使用MYISAM存储引擎,建表语句如下:

CREATE TABLE `T_MinuteStore_BAK` (

`T_MinuteStore_ID` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘行标识’,

`siteID` int(11) DEFAULT NULL COMMENT ‘站点标识’,

`genTime` datetime DEFAULT NULL COMMENT ‘监测时间’,

`itemID` int(11) DEFAULT NULL COMMENT ‘监测项目’,

`value` varchar(255) DEFAULT NULL COMMENT ‘监测值’,

`flag` varchar(255) DEFAULT NULL COMMENT ‘异常标志’,

`filterFlag` bit(1) DEFAULT NULL COMMENT ‘过滤标志’,

PRIMARY KEY (`T_MinuteStore_ID`)

) ENGINE=MYISAM AUTO_INCREMENT=188995 DEFAULT CHARSET=utf8 COMMENT=’监测分钟数据–5分钟一组数据’;

2,把T_MinuteStore表中的数据导入到新表T_MinuteStore_BAK.

insert into T_MinuteStore_BAK select * from T_MinuteStore;

提示报错: 2013 (HY000): Lost connection TO MySQL server during query

你可能想对数据表进行扫描直到第一个被损坏的行,然后从MyISAM表中得到结果?

不幸的是,运行之后的T_MinuteStore_BAK表格是只有一部份数据。

这里查看T_MinuteStore_BAK表中,主键 T_MinuteStore_ID 从最小值到160861,可以看出是被顺序插入的数据。

那么现在就好办了,说明从16081之后,有损坏的数据行。

下面作下插入数据测试,看看大约有多少行数据损坏。

insert into T_MinuteStore_BAK select * from T_MinuteStore where T_MinuteStore_ID>161000;

执行命令后,还是报错。

最后测试;

161500160861

此主键之间的数据,有损坏,其它数据恢复正常。总计100万行数据,只丢了几百行数据,完全可以承受。

3, 删除掉原表: drop table T_MinuteStore;注释掉innodb_force_recovery 之后,重启Mysql。

4,重命名 T_MinuteStore_BAK:

rename table T_MinuteStore_BAK to T_MinuteStore;

5,最后将表T_MinuteStore修改回存储引擎:

alter table T_MinuteStore engine = innodb;

最后将数据库数据导出,测试导出成功,未发现问题。备份好数据,然后更换好硬盘,重装好Mysql ,将数据导入。

测试程序,一切正常。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值