如何从ibd文件中恢复数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何从ibd文件中恢复数据相关的知识,希望对你有一定的参考价值。

    创建已经丢失的表结构

    先要安装 mysql-utilities。

    // RedHatyum -y install mysql-server mysql-utilities// Debianapt install mysql-utilities

    使用 mysqlfrm 从 .frm 文件里面找回建表语句。

    // 分析一个 .frm 文件生成建表的语句mysqlfrm --diagnostic /var/lib/mysql/test/t1.frm// 分析一个目录下的全部.frm文件生成建表语句root@username:~# mysqlfrm --diagnostic /var/lib/mysql/my_db/bk/ >createtb.sqlroot@username:~# grep "^CREATE TABLE" createtb.sql |wc -l124

    可以看到一共生成了 124 个建表语句。

    有很多时候也可以从其它库里面生成建表语句,如同一个应用的其它数据库或不同的测试环境,采用下面的 mysqldump 生成建表语句:

    mysqldump --no-data --compact my_db>createtb.sql

    登录 MySQL 生成表。

    mysql> create database my_db;mysql> use my_dbDatabase changedmysql> source createtb.sqlQuery OK, 0 rows affected (0.07 sec)......

    导入旧的数据文件

    将新建的没有包括数据的 .ibd 文件抛弃

    root@username:/var/lib/mysql/my_db# ll *.ibd|wc12411167941root@username:/var/lib/mysql/my_db# mysql -e "show tables from my_db" \\| grep -v  Tables_in_my_db  \\| while read a; do mysql -e "ALTER TABLE my_db.$a DISCARD TABLESPACE"; doneroot@username:/var/lib/mysql/my_db# ll *.ibd|wcls: cannot access '*.ibd': No such file or directory000

    可以看到所有的 .idb 文件都已经被抛弃了。然后把旧的有数据的 .ibd 文件拷贝到这个 my_db 目录下面,别忘了把属主改过来:chown mysql. *,再把这些数据文件 import 到数据库中。

    root@username:/var/lib/mysql/my_db# mysql -e "show tables from my_db" \\| grep -v  Tables_in_my_db  \\| while read a; \\do mysql -e "ALTER TABLE my_db.$a import TABLESPACE"; done

    导入完成后检查表

    使用 mysqlcheck 对数据库 my_db 下的所有表进行检查:

    root@username:/var/lib/mysql/my_db# mysqlcheck -c my_dbmy_db.cdp_backup_point                             OK......

    所有的表都导入成功。

参考技术A 在使用独立表空间的情况下,如果不慎使得innodb存储引擎的元数据文件ibdata损坏,我们还可以挽救宝贵的数据.因为在innodb使用独立表空间的情况下,ibdata文件会记录每个innodb表的id,只要使得ibd中的表id和ibdata文件中记录的表id相同,就能够打开表,读取到数据.
#创建表
CREATE TABLE `ibdtest` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`fid` int(11) NOT NULL COMMENT '表b中的id',
`content` char(255) NOT NULL COMMENT '操作内容,系统生成',
`mark` char(255) NOT NULL COMMENT '备注',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

#添加数据
INSERT ibdtest (fid,content,mark) VALUES (1,'1','1'),(2,'2','2');

SELECT * FROM ibdtest;

关闭MySQL将ibdtest.ibd copy出来,放到其他数据库中来模拟灾难.
[root@localhost ~]#/opt/soft/mysql/bin/mysqladmin -p123456 shutdown
120130 18:31:50 mysqld_safe mysqld from pidfile /opt/soft/mysql/60137.localdomain.pid ended
[1]+ Done /opt/soft/mysql/bin/mysqld_safe--defaults-file=/opt/soft/mysql/config/my.cnf --user=mysql
[root@localhost ~]# cd /home/soft/mysql/data/test/
[root@localhost test]# ll
total 1296
-rw-rw----. 1 mysql mysql 8612 Jan 18 00:06 a.frm
-rw-rw----. 1 mysql mysql 98304 Jan 18 00:24 a.ibd
-rw-rw----. 1 mysql mysql 8624 Jan 30 08:34 area.frm
-rw-rw----. 1 mysql mysql 98304 Jan 30 08:36 area.ibd
-rw-rw----. 1 mysql mysql 8642 Jan 18 00:05 b.frm
-rw-rw----. 1 mysql mysql 98304 Jan 18 00:08 b.ibd
-rw-rw----. 1 mysql mysql 8693 Jan 30 18:27 ibdtest.frm
-rw-rw----. 1 mysql mysql 98304 Jan 30 18:28 ibdtest.ibd
-rw-rw----. 1 mysql mysql 8728 Jan 6 16:23 testa.frm
-rw-rw----. 1 mysql mysql 98304 Jan 10 04:10 testa.ibd
-rw-rw----. 1 mysql mysql 8693 Jan 30 14:30 testmc.frm
-rw-rw----. 1 mysql mysql 98304 Jan 30 14:30 testmc.ibd
-rw-rw----. 1 mysql mysql 8693 Jan 30 13:54 testme.frm
-rw-rw----. 1 mysql mysql 98304 Jan 30 13:55 testme.ibd
-rw-rw----. 1 mysql mysql 8693 Jan 30 14:40 testmm.frm
-rw-rw----. 1 mysql mysql 98304 Jan 30 14:45 testmm.ibd
-rw-rw----. 1 mysql mysql 8693 Jan 30 13:40 testmu.frm
-rw-rw----. 1 mysql mysql 98304 Jan 30 13:40 testmu.ibd
-rw-rw----. 1 mysql mysql 8693 Jan 30 11:08 testmv.frm
-rw-rw----. 1 mysql mysql 98304 Jan 30 11:10 testmv.ibd
-rw-rw----. 1 mysql mysql 8694 Jan 4 21:55 testuser.frm
-rw-rw----. 1 mysql mysql 98304 Jan 4 22:04 testuser.ibd
-rw-rw----. 1 mysql mysql 8644 Jan 14 21:55 user.frm
-rw-rw----. 1 mysql mysql 98304 Jan 14 21:55 user.ibd
[root@localhost test]# cp ibdtest.ibd /home/download/
[root@localhost test]# cd /home/download/
#vim打开ibd,使用16进制查看
[root@localhost download]# vim -b ibdtest.ibd
:%!xxd
从下图中能看到 此表在 当前mysql数据库中的id为0x10,即16.

此时,我们假设灾难发生,ibdata损坏…
只剩下了ibdtest.ibd文,我们跳转到另一个mysql服务器上,用同样的建表语句创建ibdtest表.

这时我们打开这个mysql服务器下的ibdtest.ibd看看:

这个表的id为0x16,即为22,那么,我们只需将原有的ibdtest.ibd表id修改为0x16即可.
出保存的时候一定要记得使用:%!xxd -r
退出保存.
并将修改好的文件覆盖掉新的ibdtest.ibd即可,
此mysql服务器会认为该表损毁,无法打开,没关系,修改innodb_force_recovery = 6,

重启mysql服务:
Select下,就知道数据是否恢复了没有:

此时,无法执行写操作,应尽快将数据dump出来,修改innodb_force_recovery = 0,重启服务,创建新表后,把数据倒回去就ok了.恢复数据就不演示了.本回答被提问者采纳

仅使用 .frm 和 .ibd 文件恢复 MySQL 数据库[重复]

【中文标题】仅使用 .frm 和 .ibd 文件恢复 MySQL 数据库[重复]【英文标题】:Restore MySQL database using only .frm and .ibd files [duplicate] 【发布时间】:2019-01-30 12:02:36 【问题描述】:

我不小心用 InnoDB 卸载了我的 XAMPP 和 MySQL。如何在之前未导出数据库的情况下恢复文件?

由于某种原因,将旧的数据库文件复制到新的数据库数据目录中是行不通的。

我把这个扔给有需要的人,因为我花了好几个小时才修好,而且一旦你知道怎么做就很容易了。不需要神秘的 SQL 导入命令或高级 shell 命令。

【问题讨论】:

您可以简单地搜索 DBA 站点(这毕竟不是编程问题,而是管理员问题),或者 SO(无论出于何种原因,人们在这里提出各种与 IT 相关的问题)一个解法。如果您将解决方案添加到其中一个较旧的问题中以便将解决方案集中在一个地方,那就更好了。 【参考方案1】:

数据库数据默认存储在 C:\xampp\mysql\data\ 或类似目录中。文件夹是数据库表。在每个文件夹中,.frm 文件是列。 .ibd 保存行值。

首先在 PHPMyAdmin 中创建数据库。

在菜单 Recover structure > From .frm file 下获取从该站点生成的 SQL 查询:

https://recovery.twindb.com/

上传每个 .frm 文件,然后将这些查询复制并粘贴到 SQL 命令中以在 PHPMyAdmin 中创建表。

然后,在每个表上,执行以下 SQL 查询:

ALTER TABLE table_name DISCARD TABLESPACE

这将自动从数据库目录中删除新的 .ibd 文件。 将旧的 .ibd 文件复制到数据库文件夹中。 运行以下命令再次激活表:

ALTER TABLE table_name IMPORT TABLESPACE

就是这样!您应该能够再次查看和访问所有旧值。

【讨论】:

twindb 死了 ;)

以上是关于如何从ibd文件中恢复数据的主要内容,如果未能解决你的问题,请参考以下文章

从frm和ibd文件恢复表结构

从 ibd 文件恢复数据数据库不起作用

sh 脚本用于从innodb的frm和ibd文件中恢复数据。

如何使用frm和ibd文件恢复mysql数据库

mysql数据库被破坏,只剩下ibd文件时如何恢复

怎样从frm,ibd恢复MYSQL的相关推荐