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.
my_user
aber der Fehlermy_db.user