J'utilise ces étapes pour créer une table my_user
, qui existait déjà mais qui a en quelque sorte disparu de ma base de données 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)
A essayé # mysqladmin flush-tables
et a répété les étapes ci-dessus mais cela n'a pas été utile. En outre, redémarré le service mysql
, mais pas bon.
Des idées? Google m'a échoué jusqu'à présent. Merci.
Informaitons supplémentaires:
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")
my_user.frm
et my_user.ibd
des dossiers. Le dictionnaire de données a toujours une entrée pour cette table.DROP TABLE my_user;
parce que mysqld recherche le my_user.frm
première. Puisque ce n'est pas my_user.frm
, la table ne peut pas être supprimée.my_user.frm
n'existe pas, vous ne pouvez pas exécuter CREATE TABLE my_user ...
parce que mysqld pense qu'il est OK de créer la table mais passe ensuite au moteur de stockage. InnoDB dit "J'ai déjà enregistré le tablespace_id de my_user".Cette séquence d'événements peut être prouvée si vous créez la table à l'aide de MyISAM. mysqld le permettra. Une fois que vous passez à InnoDB, il revient directement au dictionnaire de données, qui est défectueux sur cette seule entrée.
J'ai deux suggestions
Ne créez plus la table avec ce nom. Utilisez un nom de table différent
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;
Cela vous amènera à changer le nom de la table dans votre code d'application
J'ai déjà traité ce problème dans mon article la table InnoDB SELECT renvoie ERREUR 2006 (HY000): le serveur MySQL est parti (après une panne de courant)
Juste pour ajouter ma solution car j'ai eu un problème similaire.
J'ai rencontré la situation désagréable où une instruction ALTER TABLE a échoué car une clé étrangère n'a pas été supprimée plus tôt. Cela a conduit à des incohérences dans le dictionnaire de données InnoDB (probablement en raison de http://bugs.mysql.com/bug.php?id=58215 ).
Question connexe ici: 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 ;
Erreur lors du renommage de './db/#sql-482c_8448f' en './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.
Comme je n'ai pas pu récupérer la table # sql-482c_8448f aux visites, j'ai décidé de la réimporter à partir d'une sauvegarde effectuée juste avant la modification. Mais cela a échoué. Enquête:
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 |
+-----------------------------------+-----------+------------------------+--------+------+
La tentative de recréation de la table sans la clé étrangère a provoqué une erreur 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
Essayer de le créer avec a provoqué une erreur 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.
Finalement, j'ai utilisé un nouveau nom de clé étrangère. Je ne m'attendais pas à ce que cela fonctionne, mais cela a permis de créer la table.
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;
Il suffit de supprimer la table après avoir supprimé l'enregistrement erroné dans INFORMATION_SCHEMA.INNODB_SYS_FOREIGN, permettant une importation avec le nom de clé étrangère d'origine.
Il existe un moyen simple de contourner ce problème, mais il est vrai que dans certaines circonstances, vous ne voudrez peut-être pas le faire. Étant donné que ce problème provient d'une référence interne InnoDB, vous pouvez simplement créer cette table avec le même nom, les mêmes colonnes, uniquement en utilisant un moteur de stockage différent. J'ai rencontré cela sur un esclave MySQL, et même si le maître à partir duquel je répliquais était InnoDB, j'ai recréé cette seule table avec MyISAM et j'ai pu me remettre en marche. J'ai spécifiquement choisi InnoDB pour mon moteur de stockage sur le maître, et sur certaines tables, ce serait également important pour l'esclave, mais dans ce cas, cela n'a eu aucun impact sur cet esclave pour cette seule table, donc c'était un moyen rapide pour contourner ce problème. Supprimer toute la base de données aurait été un projet beaucoup plus important.
Ce qui a fonctionné pour moi, c'est:
mysqlfrm
d'Oracle mysql-utitilies
** (car je n'avais pas d'autre copie/sauvegarde de la structure) par exemple: /usr/bin/mysqlfrm --diagnostic /tmp/tablebackup/MyTable.frm
MyTable
puis j'ai maintenant créé une table MyTableB
avec la structure de la table d'origine)RENAME TABLE `MyTableB` TO `MyTable`;
(notez que cela ne fonctionne que si vous pas avez innodb_force_recovery
insérez votre my.cnf
)ALTER TABLE `MyTable` DISCARD TABLESPACE;
.ibd
fichier (uniquement le fichier .ibd, pas le fichier .frm) dans le répertoire de la base de données mysql d'où il a été initialement déplacé (il ne devrait pas y en avoir ' t être un fichier .ibd existant en ce moment car il est supprimé par le DISCARD TABLESPACE
commande)ALTER TABLE `MyTable` IMPORT TABLESPACE;
* J'ai redémarré mysql après cette étape mais je ne suis pas sûr que cela soit nécessaire
** les utilitaires mysql peuvent nécessiter l'installation mysql-connector-python
d'abord
Vous avez perdu les données de la table, mais l'enregistrement sur cette table existe toujours dans "mysql/data/ibdata1". La solution la plus simple consiste à créer cette table dans une autre base de données, puis à copier des fichiers:
mysql/data/**dummy_database**/my_user.frm
mysql/data/**dummy_database**/my_user.ibd
à vous:
mysql/data/**yours_database**/my_user.frm
mysql/data/**yours_database**/my_user.ibd