Silentdoer

导航

MySQL通过frm和ibd恢复表结构和数据的办法【基于Linux和MySQL5.6.23测试】

转自:https://blog.csdn.net/hzw19920329/article/details/78045864;做了一些修改

 

【注意,show variables like '%per_table%' 的innodb_file_per_table要是ON(或1),表示frm表结构和具体数据ibd是分离的】

【然后我这边停止mysql服务是通过mysqladmin -u root shutdown实现,而启动mysql服务是通过/etc/init.d/mysqld start】

恢复表结构:
    首先创建一个数据库,可以通过navicat来创建,创建截图为:
   

    使用当前创建的数据库:use wangyi
    随意创建一张表,但是这张表的名字要和你要恢复的.frm或者.ibd一致,在此我的.frm与.ibd文件为songlyric.frm与songlyric.ibd因此我的创建表语句为:
    create table songlyric(id int);
    在执行上面的创建表语句之后,使用net stop mysql关闭数据库服务,然后用需要恢复的songlyric.frm覆盖这个新建的wangyi数据库的songlyric表的物理文件songlyric.frm,接着对配置文件(my.ini)设置innodb_force_recovery = 6,然后使用net start mysql启动服务,接着使用:desc songlyric查看该表结构,会出现下面错误信息:
   

【注意,下面所说的错误文件不一定找得到,可以通过show variables like 'log_error'来看错误文件在哪】

    针对这个问题,我们可以通过查看mysql的日志文件来解决,查看mysql安装目录下的data文件夹里面.err结尾的文件,你会发现出现下面所示的错误信息:[Warning] InnoDB: Table wangyi/songlyric contains 1 user defined columns in InnoDB, but 6 columns in MySQL.原来是因为,我们要恢复的表有6个字段,而我们在创建表的时候只创建了1个字段。
    解决方案:删除songlyric表重新创建一个包含6个字段的表【注意要drop table table_name删除而不能物理删除,如果drop提示没有找到表,可以用chown -R mysql.mysql xxx.frm(以及ibd文件)】,具体这6个字段是什么不用管的。具体执行过程为使用net stop mysql停掉服务,然后在配置文件my.ini中将innodb_force_recovery = 6注释掉(#或;均可),再net start mysql启动服务。接着在控制台先执行drop table songlyric;删除表【注意drop成功后要看下文件是否也跟着删除了,如果没有这时候可以物理删除】,再执行创建表语句,我执行的是下面的创建表语句:create table songlyric(id int,id1 int,id2 int,id3 int,id4 int,id5 int);
    紧接着按照前面的方式,使用net stop mysql关闭数据库服务,然后用需要恢复的songlyric.frm覆盖这个新建的wangyi数据库的songlyric表的物理文件songlyric.frm,接着对配置文件(my.ini)设置innodb_force_recovery = 6,然后使用net start mysql启动服务,接着使用:desc songlyric查看该表结构,输出下面结果表示恢复表结构成功【注意由于之前随便创建的表结构字段数是一样的,因此这里覆盖frm文件能够自动修正表结构】:
   

    【这一步还是需要的,这个表结构需要用得到的DDL的SQL语句重新创建,当前的这个表无法正确导入ibd文件】复制创建songlyric表的语句,我们需要通过创建表的语句重新创建表,当然在创建表之前需要将已经创建好的songlyric删除掉,具体获取创建表的语句可以通过navicat来实现,在navicat中选中songlyric表,右键对象信息,出现下面截图信息,选中DDL,里面的内容就是我们创建songlyric表的sql语句了:
  

    接着在控制台执行drop table songlyric;删除songlyric表,当然在执行删除songlyric命令之前,还需要将my.ini中的innodb_force_recovery = 6删除或者注释掉。接着执行下面命令重新创建表即可:
    CREATE TABLE songlyric (
    date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    lyricBefore text,
    lyricAfter text,
    isTraverse tinyint(1) DEFAULT NULL,
    id int(8) NOT NULL AUTO_INCREMENT,
    songUnique varchar(100) DEFAULT NULL,
    PRIMARY KEY (id),
    UNIQUE KEY songUnique (songUnique)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 

恢复表数据:【注意innodb_force_recovery = 6已经被注释,即show这个key的值此时是0】

【注意,如果有表结构语句,那么直接在新库里创建这个表结构来执行下面的语句即可(注意,表结构必须完全一致,因此frm文件还是需要保留,防止旧表后续因为业务原因增加了字段之类的)】

【注意,下面的步骤即discard和import是根本不需要重启mysql服务的】
    恢复表数据需要首先将原先的.ibd文件与原先的.frm文件解除绑定,具体就是在控制台执行下面命令:
    alter table songlyric discard tablespace;
    接着执行net stop mysql停掉服务(不一定是这个命令停止mysql服务),将需要恢复的songlyric.ibd文件覆盖这个新建的wangyi数据库的songlyric表的物理文件songlyric.ibd,执行net start mysql开启服务。【注意我后面是用Navicat执行下面的import命令一直报错表不存在,后来发现可以用chown -R mysql.mysql table_name.ibd给mysql账户赋予恢复权限后就可以了(可以vi /etc/passwd看下是否有mysql账户)】
    将复制过来的songlyric.ibd文件与songlyric.frm文件发生联系。具体执行下面命令:
    alter table songlyric import tablespace;
    这时候通过navicat查看数据表,你会发现数据已经成功恢复啦啦啦。

posted on 2021-04-22 14:54  Silentdoer  阅读(919)  评论(0编辑  收藏  举报