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。 把数据导进去:#写不进去则需要把注释掉innodb_force_recovery 之后,重启
insert into email_status_bak select * from email_status; 删除掉原表:
drop table email_status;
注释掉innodb_force_recovery 之后,重启。上面做了,这里就不需要了。
重命名:
rename table email_status_bak to email_status; 最后改回INNODB存储引擎
alter table email_status engine = innodb
注意:
在MySQL 5.5可以修改 innodb_purge_threads 的版本中(5.1版本不能修改该参数),innodb_purge_threads 和 innodb_force_recovery一起设置会出现一种loop现象:
130510 18:13:23 InnoDB: Waiting for the background threads to start
130510 18:13:24 InnoDB: Waiting for the background threads to start
130510 18:13:25 InnoDB: Waiting for the background threads to start
130510 18:13:26 InnoDB: Waiting for the background threads to start
130510 18:13:27 InnoDB: Waiting for the background threads to start
130510 18:13:28 InnoDB: Waiting for the background threads to start
130510 18:13:29 InnoDB: Waiting for the background threads to start
130510 18:13:30 InnoDB: Waiting for the background threads to start
130510 18:13:31 InnoDB: Waiting for the background threads to start
130510 18:13:32 InnoDB: Waiting for the background threads to start
130510 18:13:33 InnoDB: Waiting for the background threads to start
…………
…………
数据库无法启动,现象出现的条件是:mysql 版本 5.5
innodb_purge_threads =1,innodb_force_recovery >1 的情况(=1 没有问题),所以当需要设置innodb_force_recovery>1的时候需要关闭 innodb_purge_threads,设置他=0(默认)。
原因是:
mysql 原代码的脚本:
while (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
if (srv_thread_has_reserved_slot(SRV_MASTER) == ULINT_UNDEFINED
|| (srv_n_purge_threads == 1
&& srv_thread_has_reserved_slot(SRV_WORKER)
== ULINT_UNDEFINED)) { ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: "
"Waiting for the background threads to "
"start\n");
os_thread_sleep(1000000);
} else {
break;
}
}
总结:
这里的一个重要知识点就是 对 innodb_force_recovery 参数的理解了,要是遇到数据损坏甚至是其他的损坏。可能上面的方法不行了,需要尝试另一个方法:insert into tb select * from ta limit X;甚至是dump出去,再load回来。更多的修复方法请看 :
1: Recovering Innodb table Corruption
2:恢复损坏的InnoDB表格
3:MySQL Data Recovery
Innodb 表修复(转)的更多相关文章
- mysql 从5.1升级到5.5.33 后 innodb 表出错 及 innodb表修复
服务器使用的是mysql 5.1,了解到 5.5 系列的版本 innodb 的性能有很大提升,就想升级下.按照查到的步骤: http://www.myhack58.com/Article/sort09 ...
- MySQL数据表修复, 如何修复MySQL数据库(MyISAM / InnoDB)
常用的Mysql数据库修复方法有下面3种: 1. mysql原生SQL命令: repair 即执行REPAIR TABLE SQL语句 语法:REPAIR TABLE tablename[,table ...
- MySQL数据库INNODB 表损坏修复处理过程
MySQL数据库INNODB 表损坏修复处理过程 博客分类: mysql tomcatmysql 最近mysql数据库经常死掉,用命令net stop mysql命令也无法停掉,关闭Tomcat的时 ...
- Mysql MyISAM与InnoDB 表锁行锁以及分库分表优化
一. 两种存储引擎:MyISAM与InnoDB 区别与作用 1. count运算上的区别: 因为MyISAM缓存有表meta-data(行数等),因此在做COUNT(*)时对于一个结构很好的查询是不需 ...
- 利用mysql数据库中的TMD表修复“is marked as crashed and last (automatic?) repair failed”的错误 Database query error
===========================测试成功============================================= 1.页面出现错误:Database query ...
- MySQL InnoDB表--BTree基本数据结构
MySQL InnoDB表是索引组织表这一点应该是每一个学习MySQL的人都会首先学到的知识,这代表这表中的数据是按照主键顺序存储,也就是说BTree的叶子节点存储了所有该行的数据. 我最开始是搞Or ...
- Innodb 表空间传输迁移数据
在mysql5.5之前,mysql实例中innodb引擎表的迁移是个头疼的问题,要么使用mysqldump导出,要么使用物理备份的方法,但是在mysql5.6之后的版本中,可以使用一个新特性,方便地迁 ...
- [MySQL FAQ]系列 — 为什么InnoDB表要建议用自增列做主键
我们先了解下InnoDB引擎表的一些关键特征: InnoDB引擎表是基于B+树的索引组织表(IOT): 每个表都需要有一个聚集索引(clustered index): 所有的行记录都存储在B+树的叶子 ...
- Innodb 表空间卸载、迁移、装载
从MySQL的Innodb特性中我们知道,Inndob的表空间有共享和独享的特点,如果是共享的.则默认会把表空间存放在一个文件中(ibdata1),当开启独享表空间参数Innodb_file_per_ ...
随机推荐
- JSOI地铁换票 (贪心)
简单贪心即可. ..] of longint; var a,b:arr; i,n,m,sum:longint; procedure sort(var a:arr;l,r: longint); var ...
- Smart210学习记录-------文件操作
一.linux文件操作(只能在linux系统上用) 创建:int creat(const char* filename, mode_t mode) filename 表示要创建的文件名,mode表示对 ...
- 浅谈__declspec(dllexport)和__declspec(dllimport)
__declspec(dllimport)和__declspec(dllexport)经常是成对的,在动态链接库中__declspec(dllexport)导出dll中的成员,__declspec(d ...
- Mysql时间戳函数
1.转换为时间戳 select unix_timestamp('2013-07-15 10-06-07') 如果参数为空,则为当前时间 2.转换为时间 select from_unixtime(tim ...
- USB协议-USB的包结构及包的分类
USB是串行总线,所以数据是一位一位地在数据线上传送的.既然是一位一位地传送,就存在着一个数据位先后的问题.USB使用的是LSB在前的方式,即先出来的是最低位数据,接下来是次低位,最后是最高位(MSB ...
- PAT (Basic Level) Practise:1029. 旧键盘
[题目链接] 旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现.现在给出应该输入的一段文字.以及实际被输入的文字,请你列出肯定坏掉的那些键. 输入格式: 输入在2行中分别给出应该输入的 ...
- 在CentOS 7 上安装广告服务器 Revive Adserver
导读 Revive Adserver是一个自由开源的广告管理系统,能使出版商,广告平台和广告商在网页.应用.视频上投放并管理广告的系统.Revive Adserver以前叫做OpenX Source, ...
- springmvc学习笔记---idea创建springmvc项目
前言: 真的是很久没搞java的web服务开发了, 最近一次搞还是读研的时候, 想来感慨万千. 英雄没落, Eclipse的盟主地位隐隐然有被IntelliJ IDEA超越的趋势. Spring从2. ...
- 转载:奇异值分解(SVD) --- 线性变换几何意义(上)
本文转载自他人: PS:一直以来对SVD分解似懂非懂,此文为译文,原文以细致的分析+大量的可视化图形演示了SVD的几何意义.能在有限的篇幅把这个问题讲解的如此清晰,实属不易.原文举了一个简单的图像处理 ...
- 203. Remove Linked List Elements
Remove all elements from a linked list of integers that have value val. ExampleGiven: 1 --> 2 --& ...