薛定谔的MySQL表:存在,但又不存在

126
我遇到了最奇怪的错误。
有时,在创建或更改表时,我会收到“表已存在”的错误。但是,DROP TABLE返回“#1051-未知表格”。所以我得到了一个无法创建、无法删除的表格。
当我尝试删除数据库时,mysqld崩溃了。有时候用不同的名称创建另一个数据库会有帮助,有时候不会。
我使用一个包含约50个InnoDB表的DB。这个问题出现在不同的表中。
我在Windows、Fedora和Ubuntu上遇到过这个问题,使用MySQL 5.1和5.5。使用PDO、PHPMyAdmin或命令行时,行为相同。我使用MySQL Workbench来管理我的模式——我看到了一些相关的错误(endlines等),但对我来说都不相关。
不,这不是一个视图,而是一个表格。所有的名称都是小写的。
我尝试了我能找到的一切——刷新表格、将.frm文件从db移动到db、阅读mysql日志,没有什么帮助,只有重新安装整个东西才能解决问题。
'show tables'没有显示任何内容,'describe'表格说'table doesn't exist',没有.frm文件,但是'create table'仍然以错误结束('create table if not exists'也是如此),删除数据库会导致mysql崩溃。

相关但无用的问题:

编辑:

mysql> use askyou;
Database changed

mysql> show tables;
Empty set (0.00 sec)

mysql> create table users_has_friends (id int primary key);
ERROR 1050 (42S01): Table '`askyou`.`users_has_friends`' already exists

mysql> drop table users_has_friends;
ERROR 1051 (42S02): Unknown table 'users_has_friends'

就是这样,仍然一样:表不存在,但无法创建;

mysql> drop database askyou;
ERROR 2013 (HY000): Lost connection to MySQL server during query

名称变化,这不是我遇到的唯一一个表格/数据库出现问题的情况。


2
你能打开MySQL客户端,输入一些命令来演示问题,然后将命令和输出的完全相同的副本复制粘贴到这里吗?非常感谢您详细描述了您的问题,但如果您发布确切的命令和消息,那就更好了。 - Mark Byers
3
SHOW FULL TABLES IN askyouSELECT * FROM information_schema.TABLES WHERE TABLE_SCHEMA LIKE 'askyou' 这两个命令的执行结果都是列出在数据库 askyou 中的所有表格,但是它们的输出格式略有不同。 - eggyal
1
你是否正在使用innodb_file_per_table? - ESG
@eggyal,代码中列的正确名称应该是table_name,而不是table_schema。这个列保存的是数据库的名称。代码如下:SELECT * FROM information_schema.TABLES WHERE TABLE_SCHEMA LIKE 'askyou' - Rafael Barros
1
@RafaelBarros:非常正确。打错字了。谢谢你澄清。 - eggyal
显示剩余9条评论
11个回答

24

我曾经遇到过这种问题,当数据文件在数据目录中丢失但表定义文件存在或反之亦然。如果您使用了innodb_file_per_table,请检查数据目录,确保该表的.frm文件和.ibd文件都存在。如果是MYISAM,则应该有一个.frm.MYI和一个.MYD文件。

通常可以通过手动删除孤立文件来解决这个问题。


3
我没有使用innodb_file_per_table选项;但是,当我打开它并尝试重新创建该表时,只创建了.ibd文件,找不到.frm文件。这仅适用于某个特定的表(创建了其他10多个表的正确文件)。无论如何删除孤立的.ibd文件也没有什么帮助。 - Corkscreewe
1
我正在使用innodb_file_per_table;但是如果我删除了孤立的.frm文件,当我运行创建语句时它会被重新创建(但是创建语句会返回一个错误,.ibd文件不会被创建,我仍然无法删除它)。 - andrew lorien

15

个人猜测,innodb仍然在表空间中保留了你的表的条目,可能在ibdata中。如果你确实不需要任何数据,或者如果你有备份,请尝试以下操作:

  1. 删除所有模式(除了mysql)
  2. 关闭数据库
  3. 确保数据目录中的所有文件夹已经正确删除(同样不包括mysql)
  4. 删除ibdata和日志文件
  5. 重启数据库,它应该会从头开始重新创建表空间和日志。

2
太棒了:停止mysql,删除'ibdata1'、'ib_logfile1'和'ib_logfile0',然后重新启动mysql解决了我的问题。非常感谢! - Meilo
2
在停止服务之前和之后,备份整个数据库目录。 - John

7
解决方法很简单,至少对我有效。在另一个MySQL实例上创建名为“zzz”的表格,其中zzz是问题表的名称。 (例如,如果表名为Schrodinger,请在写入任何位置时将其替换为zzz) 表的定义无关紧要。它是一个临时的虚拟表; 将zzz.frm文件复制到应该存在表的服务器上的数据库目录中, 确保文件所有权和权限仍然正确。 在MySQL上,现在可以执行“show tables;”,并且表zzz将会出现。 mysql> drop table zzz; ...应该能够正常工作。必要时请清除目录中的任何zzz.MYD或ZZZ.MYI文件。

实际上,这个解决方案拯救了我的生命,谢谢!我复制了来自另一个数据库但是在同一台服务器上的FRM和IDB文件(相同的MySQL版本等),它似乎工作得很好。 - Pierre
我确认,这是正确的方法:复制来自另一个实例(主/从)的.frm文件并将其放入目录中,删除表格,然后您就可以再次创建该表格。 - juliangonzalez

5

我不确定这是否是直接回答此处问题的答案,但以下是我如何解决我的OS X Lion系统上的确切感知问题

我经常为一些分析工作创建/删除表格。在某个时候,我开始在脚本执行到一半时收到“表已存在”错误。重新启动服务器通常可以解决问题,但那太麻烦了。

然后我注意到在本地错误日志文件中有这样一行:

[Warning] Setting lower_case_table_names=2 because file system for /usr/local/mysql/data/ is case insensitive

这给了我一个想法,如果我的表名使用大写字母,MySQL会认为它们仍然存在,即使我已经删除它们。结果证明是这样的,只使用小写字母作为表名,问题就解决了。
在我的情况下,这很可能是某些配置错误导致的,但希望这个错误案例能够帮助其他人节省时间,不用试图寻找解决方案。

3

这是一个老问题,但我刚遇到了同样的问题,相关问题中的一个答案正是我所需要的,而且比删除文件、表格、关闭服务器等方法要简单得多。

mysqladmin -uxxxxxx -pyyyyy flush-tables

2
如果你遇到1051错误,只想删除数据库并重新导入,按照以下步骤操作即可解决问题。在Unix环境下,以root身份执行以下操作:
  • rm -rf /var/lib/mysql/YOUR_DATABASE;
  • 可选项-> mysql_upgrade --force
  • mysqlcheck -uUSER -pPASS YOUR_DATABASE
  • mysqladmin -uUSER -pPASS drop YOUR_DATABASE
  • mysqladmin -uUSER -pPASS create YOUR_DATABASE
  • mysql -uUSER -pPASS YOUR_DATABASE < IMPORT_FILE
祝好, Christus

1
我遇到了一个特定表格的问题。阅读了可能的解决方案后,我采取了一些步骤,例如:
  • 搜索孤立文件: 没有任何存在;
  • 执行: show full tables in database;: 没有看到有问题的表格;
  • 执行: describe table;: 返回table doesn't exist;
  • 执行: SELECT * FROM information_schema.TABLES WHERE TABLE_NAME='table';: 返回Empty set;
  • 通过phpMyAdmin手动搜索上面的查询: 不存在;

在这些步骤之后,我再次使用show tables;检查……哇!问题表格已经消失了。我可以创建并删除具有相同问题名称的表格,而且不需要重新启动服务器!奇怪……


1
在我的情况下,问题是通过将 mysql 数据目录的所有权更改为运行应用程序的用户来解决的。(在我的情况下,这是一个在 Jetty web 服务器上运行的 Java 应用程序。)
即使 mysql 正在运行并且其他应用程序可以正确使用它,但这个应用程序有问题。更改数据目录的所有权并重置用户密码后,一切正常工作。

0
我曾经遇到过这个问题,希望像上面发布的那样删除IBD文件会有所帮助,但实际上并没有什么区别。MySQL只是重新创建了一个新的IBD文件。在我的情况下,同一MySQL实例中的其他数据库中实际上有类似的表。由于FRM文件丢失,我从另一个数据库中的类似表中复制了FRM文件,重新启动MySQL后,该表就可以正常工作了。

0

我在创建并删除数据表后,再次想要创建时遇到了这个错误。 在我的情况下,我有一个自包含的转储文件,所以我放弃了我的模式,重新创建它,并使用该转储文件导入了表和数据。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接