MySQL > 表不存在。但它确实存在(或应该存在)

296
我更改了MySQL安装的datadir,所有的数据库都正确地移动了,但有一个数据库没有。 我可以连接并使用该数据库。 SHOW TABLES也可以正确返回所有表格,并且每个表格的文件都存在于MySQL数据目录中。
但是,当我尝试从表格中选择内容时,我收到一个错误消息,指出该表格不存在。 然而,这是没有意义的,因为我能够通过SHOW TABLES语句显示相同的表格。
我的猜测是,SHOW TABLES列出文件存在,但不检查文件是否损坏。 因此,我可以列出这些文件,但无法访问它们。
尽管如此,这只是一个猜测。 我以前从未见过这种情况。 现在,我无法重新启动数据库进行测试,但使用它的其他应用程序都运行良好。
有人知道为什么会发生这种情况吗?
示例:
mysql> SHOW TABLES;
+-----------------------+
| Tables_in_database    |
+-----------------------+
| TABLE_ONE             |
| TABLE_TWO             |
| TABLE_THREE           |
+-----------------------+
mysql> SELECT * FROM TABLE_ONE;
ERROR 1146 (42S02): Table 'database.TABLE_ONE' doesn't exist

只是复制了文件!是的,我拥有对所有内容的根访问权限。 - johnsmith
4
这些是InnoDB表吗? - Paul Dixon
1
是的,所有的表都是InnoDB。我的错,我没有说清楚! - johnsmith
最好将SQL导出并在新数据库上导入。 - DavidTaubmann
将来请查看日志文件,以便共享相关行。可能在您的系统中,您会看到类似于“[警告] InnoDB:加载表foo.bar失败,该表缺少外键索引。”这样的内容,就像其中一个答案中所看到的那样。我在这个旧问题中写下这条消息,因为评论中还没有人说查看日志文件是一个好习惯。谢谢! - Valerio Bozz
显示剩余8条评论
34个回答

290

如果还有人关心的话:

我复制数据库目录并使用命令直接粘贴,遇到了同样的问题。

cp -r /path/to/my/database /var/lib/mysql/new_database
如果你在使用一个使用InnoDB表的数据库时这样做,你可能会遇到上述所提到的“表不存在”的错误。
问题在于你需要在MySQL datadir的根目录下有 ib* 文件(例如 ibdata1ib_logfile0ib_logfile1)。
当我复制了这些文件时,它就对我起作用了。

28
救了我的命!对于其他人,如果你正在尝试将文件复制到新的安装,请确保不要覆盖现有的 ib* 文件。备份您现有的 mysql/ 目录,用您想要恢复的旧目录替换它,对所有内容进行 mysqldump,然后还原新的 mysql/ 目录。然后您就可以正确地导入 mysqldumps 了。 - Matthew
1
在Mac上复制我的数据库到本地,除了复制位于数据库目录旁边的ibdata文件外,我还必须将databasename目录、ibdata以及目录中的所有文件的所有权更改为"_mysql:wheel" (使用chown -R ...)。同样,目录内部的权限也不正确,因此需要使用chmod -R 660 databasename才能使表显示在数据库中。 - Dylan Valade
4
谢谢Mike。只是为了澄清,您需要重新启动mysql服务才能使其正常工作。至少我是这样做的,谢天谢地它起作用了。很多数据被保存在那里! - Nick Martin
18
注意: 不要忘记使用 chown!!! 因此,在 cp 之后的所有内容都要使用该命令 -> chown mysql:mysql /var/lib/mysql/ -R - Kerem
1
注意2:不要忘记应用适当的权限。在我的情况下,使用 sudo chmod -R 600 /var/lib/mysql - Augusto
显示剩余18条评论

48

对于我在Mac OS上(MySQL DMG安装)遇到的问题,简单地重启MySQL服务器解决了问题。 我猜是休眠导致的。


谢谢,这个解决方法对我也有帮助。我的问题是由于突然断电导致的机器重启后出现的。在第一次机器重启/MySQL启动后,我遇到了这个错误。然后我看到了这个答案。我通过系统偏好设置停止/启动了MySQL,问题解决了。 - Jeff Evans
3
执行以下命令以重启MySQL服务器:sudo /usr/local/mysql/support-files/mysql.server restart - laffuste
同样的问题也发生在我升级到macOS Sierra 10.12.6之后。虽然不确定是否有因果关系,但时间上看起来很可疑。 - Dave Mulligan
谢谢,有一定效果;我重新启动了(5.6,Windows)MySQL服务,然后运行了check table TABLE_ONE;。我得到了一些错误信息:“partition p2 returned error”,“idx_blah_1 is marked as corrupted”和“idx_blah_2 is marked as corrupted”。现在我又回到了运行optimize table TABLE_ONE;并且出现了错误“Table 'database.TABLE_ONE' doesn't exist”。 - Omar
在Mojave上运行MySQL。通过系统偏好设置面板重新启动没有起作用,我不得不通过命令行重新启动。 - Cortex

37

当我使用的表格名称大小写不一致时,会出现这个问题。例如表格名是'db',但在select语句中我使用了'DB'。请确保大小写一致。


20
字段名称不区分大小写,但表名是区分大小写的。这是一个常见的错误,也非常令人讨厌。 - GolezTrol

35

当将 lower_case_table_names 设置为 1 并尝试访问使用该变量默认值创建的表时,也可能会出现此错误。在这种情况下,可以将其还原为先前的值,然后就能读取表了。


7
这个东西咬了我。我撤销了它的价值,重新启动了数据库,导出了表格,将价值设置回1,重新启动了数据库,重新导入了表格,然后一切正常了。 - wmarbut
2
这就是我的问题所在。 - bluelurker

22

我不知道原因,但在我的情况下,我通过禁用并启用外键检查来解决了问题。

SET FOREIGN_KEY_CHECKS=0;
SET FOREIGN_KEY_CHECKS=1;

6
谢谢兄弟! 在我的情况下,我必须禁用foreign_key_checks并对消失的表执行一个select查询,然后表就恢复正常了。 我认为数据行中存在一些外键违规,因为在出现这个问题之前我遇到了一个被打断的程序。 - Egist Li
目前还没有找到确切的原因,但这也解决了我的问题。 - Miroslav Glamuzina
3
在我的情况下,运行SET FOREIGN_KEY_CHECKS=0;有所帮助,然后在同一控制台中执行SHOW CREATE TABLE ...,最后再启用SET FOREIGN_KEY_CHECKS=1; - Alexey Vazhnov
这对我们也有帮助,一些有用的信息在日志中: 2021-10-01T11:26:26.020904Z 8 [警告] InnoDB:加载表foo.bar失败,该表缺少外键索引。关闭“foreign_key_checks”并重试。 2021-10-01T11:26:26.020927Z 8 [警告] InnoDB:虽然表的.frm文件存在,但无法从InnoDB的内部数据字典中打开表foo/bar。请参阅http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting.html以解决此问题。 - janedbal

19
  1. 停止mysqld服务
  2. 备份mysql文件夹:cp -a /var/lib/mysql /var/lib/mysql-backup
  3. 从旧机器复制数据库文件夹到/var/lib/mysql
  4. 覆盖旧数据库中的ib*(ib_logfile*,ibdata)
  5. 启动mysqld服务
  6. 转储数据库
  7. mysqldump >dbase.mysql
  8. 停止mysql服务
  9. 删除/var/lib/mysql
  10. /var/lib/mysql-backup重命名为/var/lib/mysql
  11. 启动mysqld服务
  12. 创建数据库
  13. mysqldump < dbase.mysql

在我的情况下,我还需要执行以下操作:10.5 从 /var/lib/mysql/ 目录下删除 <db_name> 目录。 - Tony the Tech
不起作用了。 :( 表 'tablename.wp_posts' 不存在。 - Jahirul Islam Mamun
由于一些不可预见的情况,我备份了整个/var/lib/mysql文件夹,在重新安装我的Manjaro系统后,这个方法非常有效。太棒了,伙计!你可以在社交距离的情况下享用一杯啤酒。 - enchance
1
我知道这是一个旧答案,但分享任何关于为什么这样做会起作用的解释,可能是一个非常有用的答案改进。 - Valerio Bozz

14
请运行以下查询:
SELECT 
    i.TABLE_NAME AS table_name, 
    LENGTH(i.TABLE_NAME) AS table_name_length,
    IF(i.TABLE_NAME RLIKE '^[A-Za-z0-9_]+$','YES','NO') AS table_name_is_ascii
FROM
    information_schema.`TABLES` i
WHERE
    i.TABLE_SCHEMA = 'database'

很不幸,MySQL允许在表名中使用Unicode和不可打印字符。 如果您是通过从某个文档/网站复制创建代码来创建表的话,那么有可能其中包含了零宽度空格。


非常有用的帖子,谢谢!但是所有的表都是ASCII编码,名称长度正确。 - johnsmith

13

我曾经遇到了同样的问题,花费了2-3天时间进行搜索,但是对于我来说解决方案非常愚蠢。

重启mysql。

$ sudo service mysql restart

现在表格已经可以访问了。


1
完全适用于我,尽管我的命令略有不同:$ sudo /usr/local/mysql/support-files/mysql.server restart - KirstieBallance
这应该是尝试的事情清单的首要选择。值得一试,在我的情况下它起作用了。 - Coroos

12

我刚花了三天时间处理这个噩梦。理想情况下,您应该有一个可以恢复的备份,然后简单地删除受损的表格。这些类型的错误可能会导致您的ibdata1变得非常庞大(对于适度的表格而言,大小超过100GB)。

如果您没有最近的备份,例如如果您依赖于mySqlDump,则您的备份可能在过去的某个时候默默地出现故障。您需要导出数据库,但当运行mySqlDump时会出现锁定错误,因此您无法这样做。

所以,作为解决方法,进入/var/log/mysql/database_name/并删除table_name.*。

然后立即尝试转储表格;这样做现在应该可以工作了。现在将数据库恢复到新数据库并重建缺失的表格。然后转储破损的数据库。

在我们的情况下,我们还经常在所有数据库的随机时间间隔收到“mysql已断开连接”的消息;一旦移除了损坏的数据库,一切都恢复正常。


谢谢Andy,我已经得到了解决我所面临问题的线索。为了节省C盘空间,我将ibdata1从C盘某处移动到D盘。在阅读了您的评论后,幸运的是我在D盘上找到了ibdata1(以及ib_logfile1和ib_logfile0文件)。现在我会查找我移动这些文件的位置并将其恢复到原处。然后希望我的表格能够恢复。 - AKS
你如何“立即尝试转储表格”?我有同样的问题,没有备份,所以我正在寻找获取表结构的方法,但如果从目录中删除文件,则一切都会消失吗? - mmvsbg
这样做就可以了!谢谢。 - jstuardo

9

在复制idb文件之前,尝试运行SQL查询以丢弃表空间:

ALTER TABLE mydatabase.mytable DISCARD TABLESPACE;

复制idb文件

ALTER TABLE mydatabase.mytable IMPORT TABLESPACE;

重新启动MySql


你救了我 :) - l00k
@I0pan 我试过按照你提到的步骤操作,但在 ALTER TABLE mydatabase.mytable IMPORT TABLESPACE; 后它显示表不存在。但实际上它是存在的 :( - Syed Asad Abbas Zaidi
这个文档页面可能会对进一步解释有所帮助:https://dev.mysql.com/doc/refman/8.0/en/innodb-table-import.html - undefined

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