错误:表xxx的表空间存在.请在IMPORT之前丢弃表空间

Mat*_*lis 126 mysql macos navicat tablespace

我是一个相当新的MySQL,我得到一个非常有趣的错误,我无法通过谷歌和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.
Run Code Online (Sandbox Code Playgroud)

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

DROP TABLE temp;
ALTER TABLE temp DISCARD TABLESPACE;
Run Code Online (Sandbox Code Playgroud)

我收到以下错误消息:

Error : Unknown table 'database.temp'
Error : Table 'database.temp' doesn't exist
Run Code Online (Sandbox Code Playgroud)

所以这意味着我建议丢弃表空间但是当我尝试这样做时表不存在.是否有可能在DISCARD查询未检查的其他位置存在某种类型的此表的残余?有没有人知道什么可以触发所有这些 - 完全随机的似乎?

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

小智 109

这里有点晚了但通常我看到当你在'innodb_file_per_table'模式下运行时出现'tablespace full'错误时会出现这个问题.没有太多详细信息(此处更多),数据库服务器的表空间由innodb_data_file_path设置定义,默认情况下相当小.即使做得更大,"表空间已满"仍然可以发生更大的查询等(许多非表'东西'存储在那里,撤销日志,缓存等......).

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

$ ls /var/lib/mysql

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

$ mkdir /tmp/mysql_orphans
$ mv /var/lib/mysql/table3.ibd /tmp/mysql_orphans/
Run Code Online (Sandbox Code Playgroud)

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

  • 在我的情况下它不起作用...我删除了孤立的idb文件...当我去重新创建具有完全相同名称的表时,我收到一条消息说该表已经存在(为此我删除了.idb文件)...在上面的操作之后,在dir中创建了一个新的孤立的.idb文件......非常奇怪...我真的不知道该怎么做. (11认同)
  • 我的MySQL-Data目录在OS X上,Yosemite存储在`/ usr/local/mysql/data`而不是`/ var/lib/mysql /`中.否则完全解决了问题. (5认同)
  • 我有与Dimitris相同的问题-我必须从数据库创建转储,删除数据库并从转储中还原它。 (3认同)
  • @Gerfried只要我在删除文件后停止并启动MySQL进程,这对我就有效。 (2认同)
  • @DimitrisPapageorgiou只要我在删除文件后停止并启动MySQL进程,这对我有用. (2认同)

Tec*_*nic 68

Xampp和Mamp用户

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

  • 从我这里竖起大拇指!运作良好.但是,请允许我稍微更新文件夹的路径(试图找到它时感到困惑):**/Applications/XAMPP/xamppfiles/var/mysql** (2认同)

小智 22

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

我同意DangerDave的说法,所以我正在为WAMP用户提供答案.

注意:首先,您必须转到..\WAMP\Bin\MySQL\MySQL [您的MySQL版本]\Data文件夹.

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

  • 双击具有违规表的数据库的文件夹以将其打开
  • 应该没有文件[Your offending MySQL table name].frm,而应该有一个文件[Your offending MySQL table name].ibd
  • 删除 [Your offending MySQL table name].ibd
  • 然后,也将其从回收站中删除
  • 然后在数据库上运行MySQL查询,你就完成了


Acc*_*t م 19

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

这是如何与我合作的.我有.idb没有相应.frm.idb文件,每当我删除文件时,数据库会再次重新创建它.我在mysql 文档中找到了一行中的解决方案(表空间不存在部分)

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

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

我复制了另一个表.frm文件并将其命名为我丢失的表,然后进行正常的drop table查询.和voalla一起工作,桌子正常掉落!

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

  • 万一这对其他人来说不那么明显:创建.frm文件并将其放到表中后,必须删除.idb文件。 (3认同)
  • 可以确认,步骤应该是:1.删除mysql / path / table_name.idb 2.添加table_name.frm 3. DROP table_name (3认同)

jca*_*web 8

就我而言:

首先tableName.ibd从 Mysql 中删除数据库目录,然后运行:

ALTER TABLE tableName DISCARD TABLESPACE;
DROP TABLE tableName;
Run Code Online (Sandbox Code Playgroud)


小智 7

在我的情况下,唯一的工作解决方案是:

  1. CREATE TABLE bad_tableENGINE = MyISAM ......
  2. rm bad_table.ibd
  3. DROP TABLE bad_table


Chr*_*ris 6

当我有一个表在日志文件中显示完全相同的错误时,这正是我在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
Run Code Online (Sandbox Code Playgroud)

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

...already exists though the corresponding table did not exist in the InnoDB data dictionary...
Run Code Online (Sandbox Code Playgroud)

与删除表不起作用以及更改表...

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
Run Code Online (Sandbox Code Playgroud)

创建表也会失败,如下所示:

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
Run Code Online (Sandbox Code Playgroud)

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

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

然后在/ 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
Run Code Online (Sandbox Code Playgroud)

然后回到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)
Run Code Online (Sandbox Code Playgroud)

现在一切都变成正方形了,我可以重新创建一张桌子...

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

编辑:我要添加一个

restorecon -Rv /var/lib/mysql/database_name 
Run Code Online (Sandbox Code Playgroud)

复制数据库后的命令以按其应有的方式获取所有selinux上下文,即使我们几乎立即从数据库中删除它们,也可以将--archive或-a选项添加到两个cp中命令,所以实际上是archive选项可以缩短此操作:

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
Run Code Online (Sandbox Code Playgroud)

我认为更好的是以下内容,并保留为已制成的表设置的selinux上下文。

cp -a innodb_table2.frm innodb_table.frm
cp -a innodb_table2.ibd innodb_table.ibd
systemctl restart mariadb
Run Code Online (Sandbox Code Playgroud)

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


Bha*_*ana 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
Run Code Online (Sandbox Code Playgroud)

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

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

参考

  • 这不是一个独立的答案。 (9认同)