前言
整个恢复过程其实可以总结为下面几步:
(1):恢复表结构
(2):复制出来创建表的sql语句
(3):恢复表数据(在恢复表数据的时候,首先需要解除当前创建的表与默认生成的.ibd文件间的关系,接着将要恢复数据表的.ibd文件与当前创建的表联系起来即可)
一、恢复表结构
1.1创建同名表
create table town_duty_record(a int)ENGINE=InnoDB;
1.2关闭MySQL服务
1.3 复制备份的.frm覆盖新建的表.frm
1.4 开启mysql服务
1.5 在mysql安装目录data文件夹下用文本编辑器打开.err文件
[Warning] InnoDB: Table testdb/town_duty_record contains 1 user defined columns in InnoDB, but 22 columns in MySQL.
可以发现原表有22个字段
1.6 删除当前表,新建一张拥有22个字段的同名表
CREATE TABLE town_duty_record(a1 int,a2 int,a3 int,a4 int,a5 int,a6 int...a22 int)ENGINE=InnoDB;
1.7 重复步骤1.2-1.3
修改配置文件my.ini在[mysqld]下添加/修改innodb_force_recovery=6
1.8 启动mysql服务,查看表结构,发现表结构已经恢复
show create table 表名;
在navicat中找到这张表,在对象信息中复制下DDL选项卡里的内容。
1.9 停止mysql服务,修改配置文件my.ini
修改innodb_force_recovery=0
或者直接注释掉。
2.0 启动mysql服务,删掉这张表,用获得的建表语句新建表
至此,表结构已经完全恢复。
二、恢复表数据
2.1 分离表空间
使当前.ibd的数据文件和.frm分离。
ALTER TABLE town_duty_record DISCARD TABLESPACE;
2.2 复制备份的.ibd文件覆盖新的表数据
2.3 重新建立新的连接
ALTER TABLE town_duty_record IMPORT TABLESPACE;
至此,数据恢复完毕。
但是问题来了,这才是恢复了一个表呀,表太多了,肯定想批量呀。当然也可以。
三、批量恢复
3.1批量分离表空间
有了表结构以后,我们就可以知道一个库里面所有的表,不管是脱离还是导入,语句都一样,只不过换了个表名而已,所以我们要批量生成sql就行了,如下:
SELECT concat('alter table ', table_name, ' discard tablespace;')
FROM information_schema.tables
WHERE table_schema = 'water';
water就是当前数据库的名称。然后结果你就可以拿到所有的sql语句了,批量执行sql。
3.2批量拷贝.ibd
3.3批量建立新的连接
SELECT concat('alter table ', table_name, ' import tablespace;')
FROM information_schema.tables
WHERE table_schema = 'water';
批量执行sql,至此,数据全部恢复完毕。
后语
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):不执行前滚的操作。