Mysql 缺少.frm和.idb文件,无法删除表

Mysql 缺少.frm和.idb文件,无法删除表,mysql,database,innodb,Mysql,Database,Innodb,我有一个奇怪的场景,一位技术人员从我的一台服务器上删除了一个表的.frm和.idb文件,幸运的是它是一个非关键表。我正在尝试重新创建表,但是当尝试使用CREATE表、DROP表或ALTER表时,会出现错误,因为表空间仍然存在。我真的无法将好的表移动到新模式,删除旧模式,然后以这种方式重新创建表,因为模式中仍然存在无法脱机的关键表。关于如何摆脱这个“坏”表,有什么想法吗?我创建了一个测试表: mysql> use test; mysql> create table test ( id

我有一个奇怪的场景,一位技术人员从我的一台服务器上删除了一个表的.frm和.idb文件,幸运的是它是一个非关键表。我正在尝试重新创建表,但是当尝试使用CREATE表、DROP表或ALTER表时,会出现错误,因为表空间仍然存在。我真的无法将好的表移动到新模式,删除旧模式,然后以这种方式重新创建表,因为模式中仍然存在无法脱机的关键表。关于如何摆脱这个“坏”表,有什么想法吗?

我创建了一个测试表:

mysql> use test;

mysql> create table test ( id serial primary key );

mysql> insert into test () values ();
检查文件是否存在于my datadir中:

$ cd /usr/local/var/mysql/test
$ ls
db.opt   test.frm test.ibd
做不可想象的事

$ rm test.*
现在我遇到了第22条军规:

mysql> show tables;
Empty set (0.00 sec)

mysql> create table test (id serial primary key);
ERROR 1050 (42S01): Table 'test' already exists

mysql> drop table test;
ERROR 1051 (42S02): Unknown table 'test.test'
怎么办

mysql> create schema recovery;

mysql> create table recovery.test ( id serial primary key );

mysql> system cp /usr/local/var/mysql/recovery/test.frm /usr/local/var/mysql/test/
.frm
文件将表元数据存储在MySQL 5.x中。现在我有了一个
.frm
文件,MySQL允许我查询表

mysql> select * from test;
+----+
| id |
+----+
|  1 |
+----+
这很有趣-它是如何知道那一行数据的?我不是
rm
.ibd
文件吗

答:当进程仍然有一个文件句柄打开时,文件不会被真正删除。由于我没有重新启动MySQL服务器进程,
.ibd
表空间文件仍然存在,即使我将其与datadir断开链接

不管怎样,我现在可以放下桌子了。这将删除
.frm
.ibd
并关闭它们的文件句柄,因此它们将真正从文件系统中删除

mysql> drop table test;
Query OK, 0 rows affected (0.01 sec)
最后,我现在可以创建一个同名的新表,即使有不同的列

mysql> create table test ( bar int primary key );
Query OK, 0 rows affected (0.02 sec)

请注意,这仅在MySQL未重新启动时有效。这取决于*nix处理文件的方式,因此它可能无法在Windows上工作。您的意思是,只有在MySQL未重新启动的情况下才能查询表。至少,不管怎样,你至少可以删除这个表,这一部分应该是可行的,这取决于MySQL内部的细节。unix中的delete函数是“unlink”,顾名思义,它从目录中删除了对文件的引用。但是,在代码实际关闭该文件之前,该文件是存在的(并占用磁盘空间。但无法查看该文件。如果碰巧存在硬链接(
ln
,而不是
ln-s
),则“取消链接”将删除该文件的一个别名,但不会删除其他别名.unlink+close这种笨拙的方法是一种功能,当你想要一个临时表时,它会在你的程序离开时自动消失。它会对所有人隐藏文件。顺序为open(),unlink(),write…read…,然后finally close()文件.Open添加了一个目录项;unlink(取消链接)而不是close(关闭)将其从目录中删除。我对Windows的看法是,这个概念对Windows来说太陌生了,以至于不到几年前,他们添加了类似的内容,首先是“连接”,然后是更接近unix的内容。