155

我对 MySQL 还很陌生,遇到了一个非常有趣的错误,我无法通过 google 和 stackoverflow 搜索找到任何帮助。

我在 MacOS 10.8.3 上运行 MySQL 5.6.10 的本地服务器,并通过 Navicat Essentials for MySQL 管理我的数据库。

我得到的错误是,在运行和管理我的数据库几天/几周后,某些东西会触发(它看起来不完整)删除我使用 Navicat 中的查询创建的一些表。

当我尝试使用这些表运行查询时,Navicat 会警告我该特定表不存在。到目前为止一切顺利 - 这是好的部分:

当我尝试创建以前存在的表(例如名为“temp”)时,我收到以下错误消息:

Error : Tablespace for table '`database`.`temp`' exists. Please DISCARD the tablespace before IMPORT.

但是,如果我尝试删除表,或者尝试丢弃该表的表空间,请使用

DROP TABLE temp;
ALTER TABLE temp DISCARD TABLESPACE;

我收到以下错误消息:

Error : Unknown table 'database.temp'
Error : Table 'database.temp' doesn't exist

所以这意味着我被建议丢弃表空间,但是当我尝试这样做时,表不存在。是否有可能在 DISCARD 查询未检查的不同位置存在该表的某种类型的残余?有没有人知道什么会触发所有这些 - 看起来完全随机?

正如我所说,我是这个主题的新手,而且几乎一无所知。我怀疑重新启动我的笔记本电脑,即重置我的本地 MySQL 服务器,或者用户权限可能与它有关,但我只是在这里假设。

4

27 回答 27

145

这里有点晚了,但通常我已经看到当您在“innodb_file_per_table”模式下运行时出现“表空间已满”错误时会出现此问题。无需赘述(更多细节在这里),数据库服务器的表空间由 innodb_data_file_path 设置定义,默认情况下相当小。即使做得更大,“表空间已满”仍然可能发生在更大的查询等情况下(大量非表“东西”存储在那里,撤消日志,缓存等......)。

无论如何,我发现如果你查看存储每个表文件的操作系统目录,在 OSX 上默认为 /var/lib/mysql,使用 homebrew iirc 的 /usr/local/var/mysql,你会发现孤立的 tablename.ibd 文件,没有正常的伴随 tablename.frm 文件。如果您将该 .ibd 文件移动到一个安全的临时位置(为了安全起见),应该可以解决问题。

$ ls /var/lib/mysql

table1.frm
table1.idb
table2.frm
table2.idb
table3.idb <- problem table, no table3.frm
table4.frm
table4.idb

$ mkdir /tmp/mysql_orphans
$ mv /var/lib/mysql/table3.ibd /tmp/mysql_orphans/

不过需要注意的是,请确保最初导致问题的原因,例如长时间运行的查询、锁定的表等......已被清除。否则,当您第二次尝试时,您只会得到另一个孤立的 .ibd 文件。

于 2014-02-11T02:47:48.957 回答
86

Xampp 和 Mamp 用户

通过 MySQL 导入数据库(清空数据库后)时出现同样的错误。我发现我tablename.ibd留下了一个文件,而所有其他文件都被删除了。我手动删除了它mysql/data/database_name,错误消失了。

于 2014-06-08T15:59:22.820 回答
31

如果.idb删除后再次重新创建,请阅读此答案。

这就是我的工作方式。我有.idb没有对应文件.frm的文件,每当我删除.idb文件时,数据库都会重新创建它。我在 MySQL文档的一行中找到了解决方案(表空间不存在部分)

1- 在其他一些数据库目录中创建一个匹配的 .frm 文件,并将其复制到孤立表所在的数据库目录中。

2- 为原始表发出 DROP TABLE。这应该会成功删除表,并且 InnoDB 应该在错误日志中打印 .ibd 文件丢失的警告。

我复制了另一个表.frm文件并将其命名为我丢失的表,然后进行正常的删除表查询,瞧,它工作正常,表被正常删除!

我的系统是 Windows MariaDB v 10.1.8 上的 XAMPP

于 2016-09-23T02:30:37.557 回答
24

对于 WAMP [Windows 7 Ultimate x64-bit] 用户:

我同意 DangerDave 所说的,因此我正在为WAMP Users提供答案。

注意:首先,您必须转到..\WAMP\Bin\MySQL\MySQL[Your MySQL Version]\Data文件夹。

现在,您将看到所有数据库的文件夹

  • 双击包含有问题表的数据库文件夹将其打开
  • 不应该有文件[Your offending MySQL table name].frm,应该有文件[Your offending MySQL table name].ibd
  • 删除[Your offending MySQL table name].ibd
  • 然后,也将其从回收站中删除
  • 然后在数据库上运行你的 MySQL 查询,你就完成了
于 2015-10-13T04:51:23.663 回答
9

就我而言:

首先tableName.ibd从 Mysql 中删除您的数据库目录并第二次运行:

ALTER TABLE tableName DISCARD TABLESPACE;
DROP TABLE tableName;
于 2019-09-12T21:05:09.743 回答
8

这正是我在 fedora 上的 mariadb 10.2.16 中所做的,当时我有一个表在日志文件中显示完全相同的错误,我想......

2018-07-11  9:43:58 140323764213504 [Note] InnoDB: The file './database_name/innodb_table.ibd' already exists though the corresponding table did not exist in the InnoDB data dictionary. You can resolve the problem by removing the file.
2018-07-11  9:44:29 140323764213504 [Warning] InnoDB: Tablespace 'database_name/innodb_table' exists in the cache with id 2836 != 2918

您的里程和错误可能会有所不同,但我认为主要的是

...already exists though the corresponding table did not exist in the InnoDB data dictionary...

删除表无法正常工作以及更改表...

MariaDB [database_name]> drop table innodb_table;
ERROR 1051 (42S02): Unknown table 'database_name.innodb_table'

MariaDB [database_name]> alter table innodb_table discard tablespace;
ERROR 1146 (42S02): Table 'database_name.innodb_table' doesn't exist

创建表也像这样失败:

MariaDB [database_name]> create table  innodb_table(`id` int(10) unsigned NOT NULL);
ERROR 1813 (HY000): Tablespace for table '`database_name`.`innodb_table`' exists. Please DISCARD the tablespace before IMPORT

为了解决这个问题,我首先要做的是

create table  innodb_table2(`id` int(10) unsigned NOT NULL);
Query OK, 0 rows affected (0.07 sec)

然后在 /var/lib/mysql/database_name 目录中,我以 root 身份执行以下操作,确认覆盖 innodb_table.ibd 导致我们出现问题

cp -a innodb_table2.frm innodb_table.frm
cp -a innodb_table2.ibd innodb_table.ibd
systemctl restart mariadb

然后回到 mysql 控制台,我在两个表上都发出了成功的 drop 命令

MariaDB [database_name]> drop table innodb_table;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    8
Current database: database_name

Query OK, 0 rows affected (0.08 sec)

MariaDB [database_name]> drop table innodb_table2;
Query OK, 0 rows affected (0.25 sec)

现在一切都是方形的,我可以重新创建一张桌子......

MariaDB [database_name]> create table  innodb_table (`id` int(10) unsigned NOT NULL);
Query OK, 0 rows affected (0.08 sec)

编辑:我要添加一个

restorecon -Rv /var/lib/mysql/database_name 

复制数据库后的命令以按照应有的方式获取所有 selinux 上下文,即使我们几乎立即从数据库中删除它们,但在替代方案中,您可以将 --archive 或 -a 选项添加到两个 cp命令,所以是的,实际上存档选项缩短了这个:

cp innodb_table2.frm innodb_table.frm
cp innodb_table2.ibd innodb_table.ibd
chown mysql:mysql innodb_table.frm innodb_table.ibd
chmod 660 innodb_table.frm innodb_table.ibd
restorecon -Rv /var/lib/mysql/database_name
systemctl restart mariadb

到我认为更好的以下内容,它保留为已制作的表设置的 selinux 上下文。

cp -a innodb_table2.frm innodb_table.frm
cp -a innodb_table2.ibd innodb_table.ibd
systemctl restart mariadb

我已将上述较长的命令列表替换为较短的列表,该列表仍可以用 * 来缩短

于 2018-07-11T15:18:14.963 回答
8

就我而言,唯一的工作解决方案是:

  1. 创建表bad_table引擎 = MyISAM ...
  2. rm bad_table.ibd
  3. 删除表bad_table
于 2018-03-12T14:58:49.017 回答
4

删除/移动 tablename.ibd 确实对我不起作用。

我是如何解决的

由于我要删除损坏且不存在的表,因此我通过转到 phpmyadmin->database->export->selected 表备份->export(as .sql)来备份其他表。

之后,我选择了数据库名称旁边的数据库图标,然后将其删除。创建了一个新的数据库。选择您的新数据库->导入->选择您之前下载的文件->单击导入。现在我有我的旧工作表并删除了损坏的表。现在我只创建抛出错误的表。

可能我有损坏表的早期备份。

于 2015-10-17T09:56:49.713 回答
3

解决方案

但是,更简单的选择是:重新启动 MySQL,然后执行以下相同的四个步骤:

1) created a dummy table in the database;
2) discarded its tablespace;
3) moved the .ibd file into the database folder on the system;
4) attached the tablespace back to the table

这样,数据字典上的表空间id就和文件匹配了;从而导入表空间成功。

这可以让您更有信心在恢复过程甚至文件传输期间处理一些 InnoDB“问题”。

参考

于 2013-04-15T06:27:40.493 回答
3

在尝试创建用户表时,我在 wampserver 上运行它时遇到了同样的错误。我找到了一个 users.ibd 文件,删除该文件后,我再次运行了 migrate 命令并且它工作了。我的 windows 机器上的文件位于 wamp/bin/mysql/mysql5.6.12/data/myproject 中。

于 2014-04-23T21:04:19.353 回答
2

多次遇到这个问题。如果您有一个大型数据库并且想尝试避免备份/恢复(添加了丢失的表),请来回尝试几次:

删除表 my_table;

ALTER TABLE my_table 丢弃表空间;

-和-

位于 /var/lib/mysql/my_db/ 目录中的 rm my_table.ibd(无对应 my_table.frm 的孤儿)

-接着-

如果不存在则创建表my_table(...)

于 2015-09-12T16:42:24.347 回答
2

以下是解决步骤:

  1. 备份您的数据库(带有删除选项和数据的结构)
  2. 停止mysql引擎服务
  3. 从 mysql/data 中手动删除数据库目录
  4. 启动mysql引擎
  5. 使用与损坏的数据库不同的名称创建新数据库
  6. 使用新数据库中损坏的表的名称创建单个表(这是秘密)。并且最好创建具有​​完全相同结构的表。
  7. 将数据库重命名为旧的损坏数据库
  8. 恢复您的备份,您的表将正常工作。
于 2015-11-17T17:31:44.543 回答
1

我遇到过同样的问题。我重命名了数据库名称并导入它。然后它工作。

让它简单: 只需重命名数据库名称。而已。

问题是现有数据库名称在您的文件夹中有一些条目。那就是问题所在。要么您需要删除所有这些相关条目,要么只是让重命名数据库变得简单

于 2022-01-13T10:15:21.787 回答
1

当您暂停某些功能时会发生此错误。就像使用不正确的外键运行下面的查询一样。

set foreign_key_checks=0
于 2016-01-21T05:05:00.840 回答
1

有完全相同的问题;我会添加mysql@5.6(之前有 5.5 之后)。

5.6 的 brew 默认值是,innodb_file_per_table=1而在 5.5 中它们是innodb_file_per_table=0.

您现有的ibdata1文件(组合的 innodb 数据)仍将引用您尝试创建/删除的表。要么改innodb_file_per_table回 0,要么删除 ibdata1 数据文件(这会丢失你所有的数据,所以请确保你首先使用 mysqldump 或者已经有一个 .sql 转储)。

另一个让我感到困扰的 brewmysql@5.6默认设置是缺少端口,因此网络默认使用 unix 套接字,并且 mysql 客户端不断报告:

ERROR 2013 (HY000): Lost connection to MySQL server at 'sending authentication information', system error: 32

我添加<string>--port=3306</string>.plist数组中,但您也可以port=3306在您的my.cnf

然后运行brew services stop mysql@5.6进行更改brew services start mysql@5.6

于 2018-08-23T13:41:40.107 回答
0

如果您有另一台具有相同表的良好版本的服务器,您可以制作一个副本(table_copy),将 table_copy 传输到问题服务器。然后删除问题表并将table_copy重命名为table。

于 2014-04-11T14:29:22.447 回答
0

尝试删除表空间可能会给您带来其他错误。对我来说,我收到以下错误:

DROP TABLESPACE `tablename`

Error Code: 1478. Table storage engine 'InnoDB' does not support the create option 'TABLESPACE or LOGFILE GROUP' 

我的解决方案是删除数据库。这将删除与其相关的所有表空间,并允许您再次创建表。

于 2013-06-18T04:43:33.730 回答
0

对我来说,只需转到/var/lib/mysql/{db_name} (linux) 下的 MYSQL DATA 目录并删除与文件夹名称相同的{table_name}.ibd文件即可。

于 2018-12-04T11:32:57.087 回答
-1

我只直接从 wamp 删除位于我的本地主机中的旧数据库,停止所有服务,转到 wamp/bin/mysql/mysql[version]/data 我发现有问题的数据库,我删除它并重新启动 wamp 所有服务,再次创建您的数据库并完成,现在您可以导入您的表,

于 2016-09-03T07:54:00.137 回答
-1

它对我有用的唯一方法是:

  1. 创建一个类似的表
  2. 将新的相似表的 .frm 和 .idb 文件复制到损坏表的名称。
  3. 修复权限
  4. 重启 MariaDB
  5. 删除损坏的表
于 2019-08-04T10:53:34.623 回答
-1

我发现“解决”这个问题的方法相当烦人,但是有一个脚本可以处理它。

本质上,您需要ibdata1ib_logfile*文件消失(它们包含外键的映射等)。唯一安全的方法是导出所有数据库,停止 mysql,删除文件,启动 mysql,然后导入文件。

帮助解决这个问题的脚本是https://github.com/uberhacker/shrink-ibdata1,即使这个脚本的目的不同,它确实解决了这个问题。

于 2018-04-25T17:44:04.710 回答
-1

您可以以 mysql root 用户身份运行以下查询

drop tablespace `tableName`
于 2019-01-30T03:50:39.133 回答
-1

谢谢#DangerDave 这解决了我在 Magento 2 上的问题,我就是这样做的

我在vps

root@myvps [~]# cd /var/lib/mysql/mydatabasename/

root@myvps [~]# ls

检查没有.frm fie(只有.idb)的表并删除它们,

rm customer_grid_flat.ibd

系统将在运行 index:reindex 命令后重新生成表

于 2020-12-05T11:40:16.540 回答
-1

如果是 Homebrew,数据文件的目录是 /usr/local/var/mysql

查看这里使用的是哪个 my.cnf 文件是从我的环境中搜索的位置 /etc/my.cnf /etc/mysql/my.cnf /usr/local/etc/my.cnf ~/.my.cnf

所以为了清理这个错误我做了以下

mysqladmin -u root shutdown
rm /usr/local/var/mysql/<dbname>/problemtablename.ibd

注意:在我的情况下,我并不关心数据,因为它是开发设置,可能是因为我用时间机器恢复了我的笔记本电脑

于 2021-02-11T21:17:36.580 回答
-2

请在 IMPORT 之前丢弃表空间

我有同样的问题解决方案如下

  1. 首先,您必须删除您的数据库名称。如果您的数据库没有删除,那么您已经流向了我。对于 Windows 系统,您的目录将是 C:/xampp/mysql/data/yourdabasefolder remove "yourdabasefolder"

  2. 同样,您必须创建新数据库并导入旧的 sql 文件。这将是工作

谢谢

于 2018-06-15T06:14:29.203 回答
-2

我必须找到我的 MySQL 数据目录:

显示变量 WHERE Variable_Name LIKE "%dir"

然后强制删除该数据库:

须藤 rm -rf

于 2018-11-13T04:03:09.177 回答
-2

如果您遇到此问题并且没有其他选项,请将引擎更改为任何其他引擎,例如“myisam”,然后尝试创建表。

免责声明: 这不是有效的答案,因为您可能有其他存储引擎不支持的外键约束。每个存储引擎都有自己的专长来存储和访问数据,这些点也需要考虑。

于 2016-10-06T05:46:17.897 回答