Tabelle kann nicht erstellt werden, aber Tabelle existiert nicht

11

Ich verwende diese Schritte, um eine Tabelle zu erstellen my_user, die bereits vorhanden war, aber irgendwie aus meiner Datenbank verschwunden ist 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)

Versuchte # mysqladmin flush-tablesund wiederholte die obigen Schritte, aber es war nicht hilfreich. Auch der mysqlDienst neu gestartet , aber nicht gut.

Irgendwelche Ideen? Google hat mich bisher gescheitert. Vielen Dank.

Zusatzinformation:

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")
Geräuschbluten
quelle
1
Bist du sicher, dass du irgendwo keinen Tippfehler hast? Sie sagen, Sie erstellen eine Tabelle, my_useraber der Fehler my_db.user
betrifft
@mustaccio, yep hat einen Tippfehler gemacht, als der Tabellenname auf my_user gekürzt wurde (das Original hat einen längeren, verwirrenden Namen). Tatsächlich wird der CREATE TABLECode von der Doctrine ORM Library (PHP) generiert.
Noisebleed
Also, das sind nicht die tatsächlichen Namen, du
neckst
Wenn Sie den Datensatz im InnoDB-Wörterbuch aufgegeben haben, können Sie keine Tabelle mit demselben Namen erstellen. Sieht aus wie Ihr Fall, muss aber genauer untersucht werden. Versuchen Sie, my_user.frm und my_user.ibd zu fälschen und die Tabelle zu löschen.
Akuzminsky
Hat der tatsächliche Tabellenname ein seltsames Zeichen (nicht alphanumerisch)? Beginnt es mit einer Ziffer oder einem seltsamen Zeichen?
Ypercubeᵀᴹ

Antworten:

6

InnoDB-Architektur

InnoDB-Architektur

ANALYSE

  • Irgendwie hast du die my_user.frmund my_user.ibdDateien verloren. Das Datenwörterbuch enthält noch einen Eintrag für diese Tabelle.
  • Sie können nicht ausgeführt werden, DROP TABLE my_user;da mysqld nach dem my_user.frmersten sucht . Da dies my_user.frmnicht der Fall ist , kann die Tabelle nicht gelöscht werden.
  • Obwohl my_user.frmnicht vorhanden, können Sie nicht ausführen, CREATE TABLE my_user ...da mysqld der Ansicht ist, dass es in Ordnung ist, die Tabelle zu erstellen, aber dann auf die Speicher-Engine verzichtet. InnoDB sagt "Ich habe bereits die tablespace_id von my_user registriert".

Diese Abfolge von Ereignissen kann bewiesen werden, wenn Sie die Tabelle mit MyISAM erstellen. mysqld wird es zulassen. Sobald Sie zu InnoDB wechseln, kehren Sie direkt zum Datenwörterbuch zurück, das bei diesem einen Eintrag fehlerhaft ist.

Ich habe zwei Vorschläge

VORSCHLAG # 1

Erstellen Sie die Tabelle nicht mehr mit diesem Namen. Verwenden Sie einen anderen Tabellennamen

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;

Dies führt dazu, dass Sie den Tabellennamen in Ihrem Anwendungscode ändern

VORSCHLAG # 2

Ich habe dieses Problem bereits in meiner Post- InnoDB-Tabelle behandelt. SELECT gibt ERROR 2006 (HY000) zurück: Der MySQL-Server ist verschwunden (nach einem Stromausfall).

RolandoMySQLDBA
quelle
# 1 Tolle Antwort, danke für die Details. # 2 Mysqldump (ed) hat mysqld gestoppt, ibdata1 entfernt und dann neu gestartet, aber der Daemon kann nicht erfolgreich erneut gestartet werden. Ich muss besser verstehen, was los ist.
Noisebleed
Ok, jetzt funktioniert alles. Musste auch entfernen ib_logfile0und ib_logfile1(zusammen mit ibdata1). Nach dem Import konnte ich die my_userTabelle ohne Probleme erstellen . Vielen Dank, Rolando!
Noisebleed
Ich habe jetzt zwei andere Tische verloren. Ich zeichne jede ausgeführte Abfrage auf und diese Tabellen wurden nicht mit entfernt DROP TABLE. Es stimmt etwas nicht.
Noisebleed
5

Nur um meine Lösung hinzuzufügen, da ich ein ähnliches Problem hatte.

TL; DR

  • Erstellen Sie die Tabelle mit derselben Fremdschlüsselspezifikation neu, jedoch mit einem anderen Namen als zuvor in der Tabelle.
  • Löschen Sie die resultierende Tabelle (löscht auch den ursprünglichen verwaisten Fremdschlüssel)
  • Erstellen Sie die Tabelle mit dem Original oder ohne Fremdschlüssel neu

Detail

Ich bin in eine schlimme Situation geraten, in der eine ALTER TABLE-Anweisung fehlgeschlagen ist, weil ein Fremdschlüssel nicht früher gelöscht wurde. Dies führte zu einigen Inkonsistenzen im InnoDB-Datenwörterbuch (wahrscheinlich aufgrund von http://bugs.mysql.com/bug.php?id=58215 ).

Verwandte Frage hier: /programming/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  ;

Fehler beim Umbenennen von './db/#sql-482c_8448f' in './db/visits' (Fehler: 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.

Da ich die Tabelle # sql-482c_8448f nicht für Besuche wiederherstellen konnte, habe ich beschlossen, sie aus einer Sicherung erneut zu importieren, die kurz vor der Änderung durchgeführt wurde. Dies schlug jedoch fehl. Zur Untersuchung:

  • Die Einschränkung wurde aus INFORMATION_SCHEMA.TABLE_CONSTRAINTS und INFORMATION_SCHEMA.STATISTICS entfernt
  • Die Einschränkung war jedoch weiterhin in INFORMATION_SCHEMA.INNODB_SYS_FOREIGN sichtbar.
  • Die Tabelle war nicht vorhanden, daher konnte ich den Fremdschlüssel nicht löschen
  • Ich konnte die Tabelle nicht ohne Fehler erstellen

SQL / Fehler

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 |
+-----------------------------------+-----------+------------------------+--------+------+

Der Versuch, die Tabelle ohne den Fremdschlüssel neu zu erstellen, verursachte einen Fehler 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

Der Versuch, es mit zu erstellen, verursachte einen Fehler 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.

Schließlich habe ich einen neuen Fremdschlüsselnamen verwendet. Ich hatte nicht erwartet, dass dies funktioniert, aber es ermöglichte die Erstellung der Tabelle.

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;

Durch einfaches Löschen der Tabelle wurde anschließend der fehlerhafte Datensatz in INFORMATION_SCHEMA.INNODB_SYS_FOREIGN entfernt und ein Import mit dem ursprünglichen Fremdschlüsselnamen ermöglicht.

Mark C.
quelle
1

Es gibt einen einfachen Weg, dies zu umgehen, obwohl Sie dies unter bestimmten Umständen zugegebenermaßen nicht möchten. Da dieses Problem auf einer internen InnoDB-Referenz beruht, können Sie diese Tabelle einfach mit demselben Namen und denselben Spalten nur mit einer anderen Speicher-Engine erstellen. Ich bin auf einem MySQL-Slave darauf gestoßen, und obwohl der Master, von dem ich replizierte, InnoDB war, habe ich diese eine Tabelle mit MyISAM neu erstellt und konnte sie wieder in Betrieb nehmen. Ich habe InnoDB speziell für meine Speicher-Engine auf dem Master ausgewählt, und auf einigen Tabellen wäre es auch für den Slave wichtig, aber in diesem Fall hatte es keine Auswirkungen auf diesen Slave für diese eine Tabelle, also war es ein schneller Weg um dieses Problem zu umgehen. Das Löschen der gesamten Datenbank wäre ein viel größeres Projekt gewesen.

Immobilien-Entwickler
quelle
0

Was für mich funktioniert hat war:

  • Verschieben Sie zuerst die Dateien .frm und .ibd in ein anderes Verzeichnis, z. B. / tmp / tablebackup *
  • Extrahieren Sie jetzt die Tabellenstruktur aus der .frm-Datei mit mysqlfrmOracle mysql-utitilies** (da ich keine andere Kopie / Sicherung der Struktur hatte), z./usr/bin/mysqlfrm --diagnostic /tmp/tablebackup/MyTable.frm
  • Erstellen Sie eine neue Tabelle mit der Struktur der ursprünglichen Tabelle, aber mit einem anderen Namen (z. B. sagen wir, die Tabelle mit dem Problem ist, MyTabledann habe ich jetzt eine Tabelle MyTableBmit der Struktur der ursprünglichen Tabelle erstellt).
  • nächstes benennen Sie die Tabelle auf den ursprünglichen Namen aus mysql, zum Beispiel: RENAME TABLE `MyTableB` TO `MyTable`;(Beachten Sie, dass dies nur funktioniert , wenn Sie nicht haben innodb_force_recoveryin Ihrem Set my.cnf)
  • jetzt in MySQL laufen: ALTER TABLE `MyTable` DISCARD TABLESPACE;
  • Kopieren Sie dann die Originaldatei .ibd(nur die .ibd-Datei, nicht die .frm-Datei) zurück in das MySQL-Datenbankverzeichnis, aus dem sie ursprünglich verschoben wurde (es sollte derzeit keine .ibd-Datei vorhanden sein, da diese von der entfernt wird DISCARD TABLESPACEBefehl)
  • und jetzt laufen ALTER TABLE `MyTable` IMPORT TABLESPACE;

* Ich habe mysql nach diesem Schritt neu gestartet, bin mir aber nicht sicher, ob dies erforderlich ist

** MySQL-Dienstprogramme müssen möglicherweise mysql-connector-pythonzuerst installiert werden

Arthur
quelle
0

Sie haben Tabellendaten verloren, aber der Datensatz zu dieser Tabelle ist noch in "mysql / data / ibdata1" vorhanden. Die einfachste Lösung besteht darin, diese Tabelle in einer anderen Datenbank zu erstellen und anschließend Dateien zu kopieren:

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

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

zu deinen eigenen:

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

mysql/data/**yours_database**/my_user.ibd
Hevyweb
quelle