MySQL frm ibd 文件丢失的恢复

MySQL中使用InnoDB存储引擎的时候一张表对应着两个物理文件,分别为frm(存储表结构)和ibd(存储数据),但是如果这两个文件均丢失,将会发生如下情况:

test1数据库中的表结构如下:

mysql> desc emp;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(10) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> select * from emp;
+------+------+
| id   | name |
+------+------+
|    1 | z1   |
|    2 | z2   |
|    3 | z3   |
|    4 | z4   |
+------+------+
4 rows in set (0.00 sec)

先对数据库进行全备:

[root@ace ~]# mysqldump --databases test1 > fullback.dmp

然后模拟删除emp表的frm和ibd文件:

[root@ace test1]# pwd
/var/lib/mysql/test1
[root@ace test1]# rm -rf emp.*

在然后清除缓存

mysql> flush tables;
Query OK, 0 rows affected (0.00 sec)

在对表进行选择时,发现emp已经不存在了。
mysql> select * from emp;
ERROR 1146 (42S02): Table 'test1.emp' doesn't exist

此时该如何对test1中的emp表进行恢复?

我们先尝试使用全备进行恢复

发现报错:

[root@ace ~]# mysql < fullback.dmp
ERROR 1813 (HY000) at line 55: Tablespace for table '`test1`.`emp`' exists. Please DISCARD the tablespace before IMPORT.

然后对emp表进行discard tablespace 操作

mysql> alter table emp discard tablespace;
ERROR 1146 (42S02): Table 'test1.emp' doesn't exist

仍然报错。

手动创建emp表:

mysql> create table emp(id int);
ERROR 1813 (HY000): Tablespace for table '`test1`.`emp`' exists. Please DISCARD the tablespace before IMPORT.

提示表已存在。

在操作系统上可看到ibd文件已自动恢复。

[root@ace test1]# ll
total 552
-rw-rw---- 1 mysql mysql     61 Jun  2 21:12 db.opt
-rw-rw---- 1 mysql mysql   8602 Jun  5 12:56 dept.frm
-rw-rw---- 1 mysql mysql  98304 Jun  5 12:56 dept.ibd
-rw-rw---- 1 mysql mysql  65536 Jun  5 12:54 emp.ibd
-rw-rw---- 1 mysql mysql   8620 Jun  2 21:16 test_cur1.frm
-rw-rw---- 1 mysql mysql  98304 Jun  2 21:16 test_cur1.ibd
-rw-rw---- 1 mysql mysql   8620 Jun  2 21:16 test_cur2.frm
-rw-rw---- 1 mysql mysql  98304 Jun  2 21:16 test_cur2.ibd
-rw-rw---- 1 mysql mysql   8592 Jun  2 21:16 t.frm
-rw-rw---- 1 mysql mysql      0 Jun  2 21:16 t.MYD
-rw-rw---- 1 mysql mysql   1024 Jun  2 21:16 t.MYI
-rw-rw---- 1 mysql mysql   8696 Jun  2 21:16 t_user.frm
-rw-rw---- 1 mysql mysql 114688 Jun  2 21:16 t_user.ibd

现删除emp.ibd文件

然后在test库下创建一个同名的emp表

mysql> use test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

mysql> create table emp(id int);
Query OK, 0 rows affected (0.01 sec)

然后在操作系统层面将test库的emp表对应的两个物理文件拷贝到test1库的目录下。

[root@ace test1]# cp -p ../test/emp.* .
[root@ace test1]# ll
total 596
-rw-rw---- 1 mysql mysql     61 Jun  2 21:12 db.opt
-rw-rw---- 1 mysql mysql   8602 Jun  5 12:56 dept.frm
-rw-rw---- 1 mysql mysql  98304 Jun  5 12:56 dept.ibd
-rw-r----- 1 root  root    8556 Jun  5 13:01 emp.frm
-rw-r----- 1 root  root   98304 Jun  5 13:01 emp.ibd
-rw-rw---- 1 mysql mysql   8620 Jun  2 21:16 test_cur1.frm
-rw-rw---- 1 mysql mysql  98304 Jun  2 21:16 test_cur1.ibd
-rw-rw---- 1 mysql mysql   8620 Jun  2 21:16 test_cur2.frm
-rw-rw---- 1 mysql mysql  98304 Jun  2 21:16 test_cur2.ibd
-rw-rw---- 1 mysql mysql   8592 Jun  2 21:16 t.frm
-rw-rw---- 1 mysql mysql      0 Jun  2 21:16 t.MYD
-rw-rw---- 1 mysql mysql   1024 Jun  2 21:16 t.MYI
-rw-rw---- 1 mysql mysql   8696 Jun  2 21:16 t_user.frm
-rw-rw---- 1 mysql mysql 114688 Jun  2 21:16 t_user.ibd

然后回到test1库中删除emp表

mysql> drop table emp;
Query OK, 0 rows affected (0.00 sec)

发现删除成功

然后再用全备进行恢复。

[root@ace ~]# mysql < fullback.dmp
[root@ace ~]#

恢复成功,无任何报错信息。

mysql> select * from emp;
+------+------+
| id   | name |
+------+------+
|    1 | z1   |
|    2 | z2   |
|    3 | z3   |
|    4 | z4   |
+------+------+
4 rows in set (0.00 sec)

数据也已完全恢复。

以上MySQL小白的个人愚见,欢迎大师指点。

你可能感兴趣的:(MySQL)