【问题标题】:Error: Tablespace for table xxx exists. Please DISCARD the tablespace before IMPORT错误:表 xxx 的表空间存在。请在 IMPORT 之前丢弃表空间
【发布时间】:2013-03-28 23:49:53
【问题描述】:

我对 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 服务器,或者用户权限可能与它有关,但我只是在这里假设。

【问题讨论】:

标签: mysql macos navicat tablespace


【解决方案1】:

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

无论如何,我发现如果你查看存储每个表文件的 OS 目录,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 文件。

【讨论】:

  • 我的 MySQL-Data 目录在 OS X Yosemite 上存储在 /usr/local/mysql/data 而不是 /var/lib/mysql/。否则完美解决问题。
  • 在我的情况下它不起作用...我删除了孤立的 idb 文件...当我重新创建具有完全相同名称的表时,我收到一条消息说该表已经存在(为此我删除了 .idb 文件)...在上述操作之后,在目录中创建了一个新的孤立的 .idb 文件...非常奇怪...我真的不知道该假设什么。
  • 我和 Dimitris 有同样的问题 - 我必须从数据库创建转储,删除数据库并从转储中恢复。
  • @Gerfried 只要我在删除文件后停止并启动 MySQL 进程,这对我有用。
  • @DimitrisPapageorgiou 只要我在删除文件后停止并启动 MySQL 进程,这对我有用。
【解决方案2】:

Xampp 和 Mamp 用户

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

【讨论】:

  • 这个答案对不使用 XAMPP 的人有帮助吗?
  • 向我竖起大拇指!运作良好。但是,请允许我稍微更新一下文件夹的路径(试图找到它时感到困惑):/Applications/XAMPP/xamppfiles/var/mysql
  • 使用这个从 linux mint 的存储引擎中开发了一个 168 错误,没有使用 Xampp 或 Mamp(没有批评,只是通知)
  • 有效!我删除了一个损坏的 .ibd 文件,然后可以再次创建表。 Ubuntu 16,mariadb
  • Docker 也是如此(如果 docker 崩溃或主机重新启动,您的同步文件夹中可能有导致此错误的死日期)
【解决方案3】:

如果您在删除 .idb 后重新创建它,请阅读此答案。

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

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

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

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

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

【讨论】:

  • 如果其他人不明白这一点:当您创建 .frm 文件并删除表时,必须删除 .idb 文件。
  • 可以确认,步骤应该是:1.删除mysql/path/table_name.idb 2.添加table_name.frm 3.DROP table_name
  • 这对我有用。谢谢。我在删除 FK 时遇到了这个错误,在它之后,我立即停止了 mysql。我认为这是我的表定义数据已损坏。
  • 放入文件后记得重启mysql,然后尝试删除它
  • 在 mysql > data> mysql 中,我需要一个 .frm 文件。我可以复制这个吗?
【解决方案4】:

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

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

注意:首先,你必须进入你的..\WAMP\Bin\MySQL\MySQL[Your MySQL Version]\Data文件夹。 p>

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

  • 双击有问题表的数据库文件夹将其打开
  • 不应该有一个文件[Your offending MySQL table name].frm,而是应该有一个文件[Your offending MySQL table name].ibd
  • 删除[Your offending MySQL table name].ibd
  • 然后,也将其从回收站中删除
  • 然后在数据库上运行 MySQL 查询就大功告成了

【讨论】:

    【解决方案5】:

    就我而言:

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

    ALTER TABLE tableName DISCARD TABLESPACE;
    DROP TABLE tableName;
    

    【讨论】:

    • 谢谢,就我而言,我有 1) 停止数据库服务器 (service mysql stop) 2) 删除 idb 文件 3) 启动数据库服务器 (service mysql start) 没有运行 alter 和 drop 查询
    • 你在Windows中的数据库目录默认在C:\ProgramData\MySQL
    • 不,数据库目录不一定在 C:\ProgramData 中。如果 OP 使用 XAMPP,默认情况下,它可能在他告诉 XAMPP 安装放置 xampp 文件夹的位置下。我的是'D:'目录下的'xampp'。无论您使用的是 Windows 10、Windows 7 还是其他任何系统,这都是正确的。
    • 感谢您的解决方案。它对我有用。
    【解决方案6】:

    就我而言,唯一可行的解​​决方案是:

    1. 创建表bad_table ENGINE=MyISAM ...
    2. rm bad_table.ibd
    3. 删除表bad_table

    【讨论】:

    • 为我工作! [错误] InnoDB:文件“./dbname/tablename.ibd”已经存在,尽管相应的表在 InnoDB 数据字典中不存在。您是否在不使用 SQL 命令 DISCARD TABLESPACE 和 IMPORT TABLESPACE 的情况下移动了 InnoDB .ibd 文件,或者 mysqld 在 CREATE TABLE 中间崩溃了吗?您可以通过删除 MySQL 的 'datadir' 下的文件 './dbname/tablename.ibd' 来解决问题。
    • 无法创建表,因为存在表空间。
    • 这对我不起作用。在我想用相同的引擎重新创建表后,ibd 文件不断出现。
    【解决方案7】:

    这正是我在 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...
    

    drop table 不能像 alter table 一样工作...

    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 控制台,我在两个表上都发出了成功的删除命令

    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上下文的命令 它们应该是这样的,即使我们正在从 数据库几乎立即,但在替代方案中,您可以添加 两个 cp 命令的 --archive 或 -a 选项,所以实际上是 存档选项缩短了这个:

    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
    

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

    缩短

    【讨论】:

    • 这对我来说在 CentOS MariaDB 10.2.31 上运行良好。我一直在寻找不需要重启 MySQL 服务的解决方案,就是这样。关键是创建一组干净的 innodb_table2 文件(innodb_table2.frm 和 innodb_table2.ibd)并将它们放在 innodb_table 文件上。
    • 这对我也适用于 CentOS 10.1.48-MariaDB
    • 我的错误导致问题重复:状态:“InnoDB:错误:试图打开以前打开的表空间。以前的表空间 mysql/innodb_table_stats 使用空间 ID:203534 在文件路径:./mysql/ innodb_table_stats.ibd。无法打开表空间 mysql/innodb_table_stats2,它使用空间 ID:203534 在文件路径:./mysql/innodb_table_stats2.ibd"
    【解决方案8】:

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

    我是如何解决的

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

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

    我可能对损坏的表进行了较早的备份。

    【讨论】:

      【解决方案9】:

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

      【讨论】:

        【解决方案10】:

        解决方案

        但是,更简单的选择是:重新启动 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“问题”。

        ref

        【讨论】:

        • 这不是一个独立的答案。
        【解决方案11】:

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

        删除表 my_table;

        ALTER TABLE my_table 丢弃表空间;

        -和-

        rm my_table.ibd(orphan w/o 对应的 my_table.frm)位于 /var/lib/mysql/my_db/ 目录中

        -然后-

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

        【讨论】:

          【解决方案12】:

          以下是解决步骤:

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

          【讨论】:

            【解决方案13】:

            遇到了完全相同的问题;我会添加 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 转储)。

            另一个 brew mysql@5.6 默认让我讨厌的是缺少端口,因此网络默认为 unix 套接字,并且 mysql 客户端不断报告:

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

            我将&lt;string&gt;--port=3306&lt;/string&gt; 添加到.plist 数组中,但您也可以在my.cnf 中指定port=3306

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

            【讨论】:

            • 将 innodb_file_per_table 设置为 0 并重新启动,在创建替代表并将它们的 .ibd 和 .frm 复制到我损坏的表文件之上,然后返回 innodb_file_per_table = 1 部分解决了问题(现在替代表让 MariaDB 抱怨表空间)。
            【解决方案14】:

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

            set foreign_key_checks=0
            

            【讨论】:

              【解决方案15】:

              我遇到了同样的问题。我重命名了数据库名称并导入它。然后就可以了。

              简单: 只需重命名数据库名称。就是这样。

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

              【讨论】:

                【解决方案16】:

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

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

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

                【讨论】:

                • 不幸的是,这就像说'我有一个螺丝,使用锤子会返回这个错误,所以我的解决方案是在上面放一块巨石'。真正的价值在于弄清楚如何在不破坏整个数据库的情况下修复这个表。
                • 噢!我希望这将是my question 的替代解决方案(我将其作为答案发布),但我已经完成了重命名表/删除数据库的过程的一半。我现在有点讨厌 InnoDB。
                • 但是我对数据库进行了核对,重新创建了它,并且仍然有这个问题!
                • @TRiG 你重启服务器了吗?
                • 我想我会问一个单独的问题,@Aris。就我而言,它位于 Ubuntu 桌面上。我不仅重启了 MySQL,还重启了整台机器,好几次。还使用rm -r 手动删除了数据库文件夹。这很烦人,但也不是令人讨厌的。
                【解决方案17】:

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

                【讨论】:

                  【解决方案18】:

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

                  【讨论】:

                    【解决方案19】:

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

                    【讨论】:

                      【解决方案20】:

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

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

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

                      【讨论】:

                        【解决方案21】:

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

                        drop tablespace `tableName`
                        

                        【讨论】:

                        • 如果是 MariaDb,正如@avibrazil 所引用的,您不能执行“删除表空间tablename”。请参阅mariadb.com/kb/en/drop-tablespace --->“MariaDB 不支持 DROP TABLESPACE 语句。”
                        • 帖子是关于 MySQL 5.6 而不是 MariaDB。
                        【解决方案22】:

                        对我有用的唯一方法是:

                        1. 创建一个类似的表
                        2. 将新的相似表的 .frm 和 .idb 文件复制到损坏表的名称。
                        3. 修复权限
                        4. 重启 MariaDB
                        5. 删除损坏的表

                        【讨论】:

                          【解决方案23】:

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

                          我在 vps 上

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

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

                          rm customer_grid_flat.ibd
                          

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

                          【讨论】:

                            【解决方案24】:

                            如果是 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
                            

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

                            【讨论】:

                              【解决方案25】:

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

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

                              【讨论】:

                                【解决方案26】:

                                请在导入前丢弃表空间

                                我得到了同样的问题解决方案如下

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

                                2. 再次,您必须创建新数据库并导入旧的 sql 文件。会成功的

                                谢谢

                                【讨论】:

                                  【解决方案27】:

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

                                  在 Variable_Name LIKE "%dir" 的地方显示变量

                                  然后强制删除该数据库:

                                  sudo rm -rf

                                  【讨论】:

                                    猜你喜欢
                                    • 1970-01-01
                                    • 2013-07-28
                                    • 1970-01-01
                                    • 2016-07-05
                                    • 1970-01-01
                                    • 2018-03-27
                                    • 2015-03-12
                                    • 1970-01-01
                                    • 2016-05-05
                                    相关资源
                                    最近更新 更多