无法创建表,但表不存在


11

我正在使用这些步骤来创建一个表my_user,该表已经存在,但以某种方式从我的数据库中消失了my_db

mysql> USE my_db;
mysql> DROP TABLE my_user;
mysql> ERROR 1051 (42S02): Unknown table 'my_user'
mysql> CREATE TABLE my_user (id INT AUTO_INCREMENT NOT NULL, username VARCHAR(255), group_id VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
mysql> ERROR 1005 (HY000): Can't create table 'my_db.my_user' (errno: -1)

尝试# mysqladmin flush-tables并重复了上述步骤,但这没有帮助。另外,重新启动了mysql服务,但效果不佳。

有任何想法吗?到目前为止,谷歌使我失败了。谢谢。

额外信息:

mysql> SHOW engine innodb STATUS;
------------------------
LATEST FOREIGN KEY ERROR
------------------------
140703 15:15:09 Error in foreign key constraint of table my_db/my_user
there is no index in the table which would contain
the columns as the first columns, or the data types in the
table do not match the ones in the referenced table
or one of the ON ... SET NULL columns is declared NOT NULL. Constraint:
,
  CONSTRAINT "FK_CFBD431E285FAC6D" FOREIGN KEY ("group_id") REFERENCES "my_group" ("id")

1
您确定某个地方没有错字吗?您说您正在创建表,my_user但该错误与my_db.user... 有关
mustaccio 2014年

@mustaccio,当将表名缩短为my_user时,会出现错字(原始表名较长,令人困惑)。实际上,CREATE TABLE代码是由Doctrine ORM库(PHP)生成的。
2014年

所以,这些不是真实的名称,您只是在逗我们...
mustaccio 2014年

如果您在InnoDB词典中放弃了记录,则将不允许您创建具有相同名称的表。看起来像您的情况,但需要更多调查。尝试放置伪造的my_user.frm和my_user.ibd并删除表。
2014年

实际的表名是否有任何奇怪的字符(不是字母数字)?它以数字还是怪异的字符开头?
ypercubeᵀᴹ

Answers:


7

InnoDB架构

InnoDB架构

分析

  • 不知何故,您丢失了my_user.frmmy_user.ibd文件。数据字典仍然具有该表的条目。
  • 您无法运行,DROP TABLE my_user;因为mysqld查找第my_user.frm一个。由于为no my_user.frm,因此无法删除该表。
  • 尽管my_user.frm不存在,但是您无法运行,CREATE TABLE my_user ...因为mysqld认为可以创建表,但随后将其提交给存储引擎。InnoDB说“我已经注册了my_user的tablespace_id”。

如果使用MyISAM创建表,则可以证明事件的顺序。mysqld将允许它。切换到InnoDB后,它会立即返回到数据字典,这在该条目上是有问题的。

我有两个建议

建议#1

不再使用该名称创建表。使用其他表格名称

CREATE TABLE my_usertable (id INT AUTO_INCREMENT NOT NULL, username VARCHAR(255), group_id VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;

这将导致您在应用程序代码中更改表名

建议#2

在发布InnoDB表SELECT返回ERROR 2006(HY000)之前,我已经解决了此问题:MySQL服务器已消失(断电后)


#1好答案,谢谢你的细节。#2 Mysqldump(ed),停止mysqld,删除ibdata1,然后重新启动,但无法使守护程序再次成功启动。需要更好地了解正在发生的事情。
2014年

好的,现在一切正常。还必须删除ib_logfile0ib_logfile1(以及ibdata1)。导入后,我可以创建my_user表而没有任何问题。谢谢罗兰多!
2014年

我现在输了另外两张桌子。我正在记录每个执行的查询,并且未使用删除这些表DROP TABLE。发生错误。
2014年

谢谢。有同样的问题。数据库中的1个表丢失,由于无法创建表,因此无法从备份中还原该表。
Gigih Aji Ibrahim

5

只是添加我的解决方案,因为我遇到类似的问题。

TL; DR

  • 重新创建具有相同外键规范但名称与表先前所拥有名称不同的表。
  • 删除结果表(还将删除原始的孤儿外键)
  • 用原始或没有外键重新创建表

详情

我遇到一个令人讨厌的情况,由于未提前删除外键,所以ALTER TABLE语句失败。这导致InnoDB数据字典中出现一些不一致(可能是由于http://bugs.mysql.com/bug.php?id=58215引起的)。

此处相关问题:https : //stackoverflow.com/questions/16857451/error-in-foreign-key-constraint-on-a-droped-table

mysql> ALTER TABLE `visits` CHANGE COLUMN `variation_visitor_id` `variation_visitor_id` INT(11) NOT NULL  ;

将'./db/#sql-482c_8448f'重命名为'./db/visits'时出错(错误号:150)

mysql> SHOW ENGINE INNODB STATUS;

Error in foreign key constraint of table db/visits:
 FOREIGN KEY (`variation_visitor_id`) REFERENCES `variations_visitors` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html 
for correct foreign key definitippon.

由于无法恢复要访问的#sql-482c_8448f表,因此我决定从更改之前进行的备份中重新导入该表。但是,这失败了。调查中:

  • 该约束已从INFORMATION_SCHEMA.TABLE_CONSTRAINTS和INFORMATION_SCHEMA.STATISTICS中删除
  • 但是该约束在INFORMATION_SCHEMA.INNODB_SYS_FOREIGN中仍然可见。
  • 该表不存在,所以我无法删除外键
  • 我不能没有错误地创建表

SQL /错误

mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN WHERE ID='db/fk_visits_variations_visitors1';

+-----------------------------------+-----------+------------------------+--------+------+
| ID                                | FOR_NAME  | REF_NAME               | N_COLS | TYPE |
+-----------------------------------+-----------+------------------------+--------+------+
| db/fk_visits_variations_visitors1 | db/visits | db/variations_visitors |      1 |   48 |
+-----------------------------------+-----------+------------------------+--------+------+

尝试重新创建没有外键的表时导致错误150

mysql>

SET UNIQUE_CHECKS = 0;
SET FOREIGN_KEY_CHECKS = 0;

CREATE TABLE `visits` (
  `id` INT(11) NOT NULL AUTO_INCREMENT  ,
  `variation_visitor_id` INT(11) NOT NULL  ,
  PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

SET FOREIGN_KEY_CHECKS = 1;
SET UNIQUE_CHECKS = 1;

ERROR 1005 (HY000) at line 26: Can't create table 'db.visits' (errno: 150)

mysql> SHOW ENGINE INNODB STATUS;

Error in foreign key constraint of table db/visits:
there is no index in the table which would contain
the columns as the first columns, or the data types in the
table do not match the ones in the referenced table
or one of the ON ... SET NULL columns is declared NOT NULL. Constraint:
,
  CONSTRAINT "fk_visits_variations_visitors1" FOREIGN KEY ("variation_visitor_id") REFERENCES "variations_visitors" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION

尝试创建它导致错误121

mysql>

SET UNIQUE_CHECKS = 0;
SET FOREIGN_KEY_CHECKS = 0;

CREATE TABLE `visits` (
  `id` INT(11) NOT NULL AUTO_INCREMENT  ,
  `variation_visitor_id` INT(11) NOT NULL  ,
  PRIMARY KEY (`id`),
  KEY `fk_visits_variations_visitors1` (`variation_visitor_id`),
  CONSTRAINT `fk_visits_variations_visitors1` FOREIGN KEY (`variation_visitor_id`) REFERENCES `variations_visitors` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

SET FOREIGN_KEY_CHECKS = 1;
SET UNIQUE_CHECKS = 1;

ERROR 1005 (HY000) at line 26: Can't create table 'db.visits' (errno: 121)

mysql> SHOW ENGINE INNODB STATUS;

Error in foreign key constraint creation for table `db`.`visits`.
A foreign key constraint of name `db`.`fk_visits_variations_visitors1`
already exists. (Note that internally InnoDB adds 'databasename'
in front of the user-defined constraint name.)
Note that InnoDB's FOREIGN KEY system tables store
constraint names as case-insensitive, with the
MySQL standard latin1_swedish_ci collation. If you
create tables or databases whose names differ only in
> the character case, then collisions in constraint
names can occur. Workaround: name your constraints
explicitly with unique names.

最终,我使用了新的外键名称。我没想到这会起作用,但是它允许创建表。

mysql>

SET UNIQUE_CHECKS = 0;
SET FOREIGN_KEY_CHECKS = 0;

CREATE TABLE `visits` (
  `id` INT(11) NOT NULL AUTO_INCREMENT  ,
  `variation_visitor_id` INT(11) NOT NULL  ,
  PRIMARY KEY (`id`),
  KEY `fk_visits_variations_visitors2` (`variation_visitor_id`),
  CONSTRAINT `fk_visits_variations_visitors2` FOREIGN KEY (`variation_visitor_id`) REFERENCES `variations_visitors` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

SET FOREIGN_KEY_CHECKS = 1;
SET UNIQUE_CHECKS = 1;

之后,只需删除表,即可删除INFORMATION_SCHEMA.INNODB_SYS_FOREIGN中的错误记录,从而允许使用原始外键名称进行导入。


1

解决此问题的方法很简单,尽管诚然,在某些情况下,您可能不想这样做。由于此问题源于InnoDB内部引用,因此仅使用不同的存储引擎即可简单地创建具有相同名称,相同列的表。我在一个MySQL从属服务器上遇到了这个问题,即使我要复制的主服务器是InnoDB,我也使用MyISAM重新创建了这个表并能够恢复运行。我特别选择了InnoDB作为我在主服务器上的存储引擎,在某些表上,它对从服务器也很重要,但是在这种情况下,对于此一个表,它对该从服务器的影响为零,因此这是一种快速的方法解决这个问题。删除整个数据库将是一个更大的项目。


0

对我有用的是:

  • 首先将.frm和.ibd文件移动到另一个目录,例如/ tmp / tablebackup *
  • 现在使用mysqlfrmOracle mysql-utitilies** 从.frm文件中提取表结构(因为我没有该结构的其他副本/备份),例如:/usr/bin/mysqlfrm --diagnostic /tmp/tablebackup/MyTable.frm
  • 创建一个具有原始表结构但名称不同的新表(例如,假设有问题的表现MyTable在是MyTableB具有原始表结构的表)
  • 接下来的表从MySQL中重命名为原来的名称,例如:RENAME TABLE `MyTableB` TO `MyTable`;(注意,这只是工作,如果你不是已经innodb_force_recovery在你的设置my.cnf
  • 现在在mysql中运行: ALTER TABLE `MyTable` DISCARD TABLESPACE;
  • 然后将原始.ibd文件(仅.ibd文件,而不是 .frm文件)复制回其最初移出的mysql数据库目录中(此刻不应该存在现有的.ibd文件,因为该文件会被删除。DISCARD TABLESPACE命令)
  • 现在运行 ALTER TABLE `MyTable` IMPORT TABLESPACE;

* 我在此步骤后重新启动mysql,但不确定是否需要

** mysql-utilities可能需要mysql-connector-python先安装


0

您丢失了表数据,但是关于该表的记录仍然存在于“ mysql / data / ibdata1”中。最简单的解决方案是在其他数据库中创建此表,然后复制文件:

mysql/data/**dummy_database**/my_user.frm

mysql/data/**dummy_database**/my_user.ibd

对自己的:

mysql/data/**yours_database**/my_user.frm

mysql/data/**yours_database**/my_user.ibd
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.