テーブルを作成できませんが、テーブルが存在しません


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サービスを再起動しましたが、良くありません。

何か案は?Googleは今のところ失敗しました。ありがとう。

追加情報:

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

@mustaccio、テーブル名をmy_userに短縮すると、誤植がありました(元の名前は長くて混乱します)。実際、CREATE TABLEコードはDoctrine ORMライブラリ(PHP)によって生成されます。
2014

だから、これらは実際の名前ではなく、あなたは私たちをからかっているだけです...
mustaccio

InnoDBディクショナリのレコードを破棄した場合、同じ名前のテーブルを作成できません。あなたのケースのように見えますが、さらに調査が必要です。偽のmy_user.frmとmy_user.ibdを配置して、テーブルをドロップしてみてください。
アクズミンスキー2014

実際のテーブル名に奇妙な文字(英数字ではない)が含まれていますか?数字または変な文字で始まりますか?
ypercubeᵀᴹ

回答:


6

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が、ストレージエンジンにテーブルが、その後延期を作成するために、OKであると考えているため。InnoDBは、「my_userのtablespace_idがすでに登録されている」と述べています。

この一連のイベントは、MyISAMを使用してテーブルを作成する場合に証明できます。mysqldはそれを許可します。InnoDBに切り替えると、データディクショナリに戻りますが、その1つのエントリに障害があります。

2つの提案があります

提案#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

  • mysqldumpすべてのデータ、トリガー、およびストアドプロシージャ
  • バックアップibdata1
  • ibdata1を削除する
  • mysqldumpをリロードします
  • StackOverflow投稿の詳細な手順

私は以前にこの問題に対処しましたが、InnoDBテーブルSELECTはエラー2006(HY000)を返します:MySQLサーバーが停止しました(停電後)


#1すばらしい答え、詳細をありがとう。#2 Mysqldump(ed)、mysqldの停止、ibdata1の削除、その後再起動しましたが、デーモンを再び正常に起動できません。何が起こっているのかをよりよく理解する必要があります。
2014

さて、すべてが今働いています。また、削除する必要がありましたib_logfile0し、ib_logfile1(一緒にibdata1)。インポート後、my_user問題なくテーブルを作成できました。Rolando、ありがとう!
2014

他の2つのテーブルを失いました。実行されたすべてのクエリを記録していますが、それらのテーブルはを使用して削除されませんでしたDROP TABLE。何か問題が起こっています。
ノイズブリード2014

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'への名前変更時のエラー(errno: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テーブルをVisitsにリカバリできなかったため、変更の直前に実行されたバックアップから再インポートすることにしました。しかし、これは失敗しました。調査について:

  • 制約は、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

これを回避する簡単な方法が1つありますが、確かに、特定の状況ではこれを実行したくない場合があります。この問題はInnoDB内部参照に起因するため、異なるストレージエンジンを使用する場合にのみ、同じ名前、同じ列でこのテーブルを作成できます。MySQLスレーブでこれに遭遇し、レプリケート元のマスターがInnoDBであったとしても、MyISAMでこの1つのテーブルを再作成し、復旧して実行することができました。私は特にマスターのストレージエンジンにInnoDBを選択しましたが、一部のテーブルではスレーブでも重要ですが、この場合、この1つのテーブルではこのスレーブに影響を与えなかったため、迅速な方法でしたこの問題を回避するには。データベース全体を削除することは、はるかに大きなプロジェクトでした。


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ファイル(.frm ファイルではなく .ibdファイルのみ)を元の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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.