Details
-
Bug
-
Status: Closed (View Workflow)
-
Minor
-
Resolution: Fixed
-
10.0.16
-
Linux
Description
Reproduce code:
CREATE TABLE `#departments` ( |
`id_depart` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, |
PRIMARY KEY (`id_depart`) |
) ENGINE=INNODB;
|
|
CREATE TABLE `crm_client` ( |
`id_client` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, |
PRIMARY KEY (`id_client`) |
) ENGINE=INNODB;
|
|
|
CREATE TABLE `#departments_pos` ( |
`id_pos` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, |
`id_depart` INT(10) UNSIGNED NOT NULL, |
`id_client_bank` INT(10) UNSIGNED NOT NULL, |
PRIMARY KEY (`id_pos`), |
KEY `id_depart` (`id_depart`), |
CONSTRAINT `#departments_pos_ibfk_1` FOREIGN KEY (`id_depart`) REFERENCES `#departments` (`id_depart`) |
) ENGINE=INNODB;
|
|
|
ALTER TABLE `#departments_pos` |
ADD FOREIGN KEY (`id_client_bank`) REFERENCES `crm_client`(`id_client`); |
Error Code: 1050
|
Table './test2/@0023departments_pos' already exists
|
Workaround is manual define CONSTRAINT name
ALTER TABLE `#departments_pos` |
ADD CONSTRAINT `#departments_pos_ibfk_2` FOREIGN KEY (`id_client_bank`) REFERENCES `crm_client`(`id_client`); |
Yet another example:
CREATE TABLE `#departaments` ( |
`id_depart` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, |
PRIMARY KEY (`id_depart`) |
) ENGINE=INNODB DEFAULT CHARSET=utf8 |
|
|
CREATE TABLE `#departaments_tree` ( |
`id_depart` INT(10) UNSIGNED NOT NULL, |
`id_depart_in` INT(10) UNSIGNED NOT NULL, |
PRIMARY KEY (`id_depart`,`id_depart_in`), |
CONSTRAINT `#departaments_tree_ibfk_1` FOREIGN KEY (`id_depart`) REFERENCES `#departaments` (`id_depart`) |
) ENGINE=INNODB DEFAULT CHARSET=utf8 |
|
|
ALTER TABLE `#departaments_tree` |
ADD FOREIGN KEY (`id_depart_in`) REFERENCES `#departaments`(`id_depart`) |
Error CODE: 1050
|
TABLE './test3/@0023departaments_tree' already EXISTS
|
Workaround is manual define CONSTRAINT name
ALTER TABLE `#departaments_tree` |
ADD CONSTRAINT `#departaments_tree_ibfk_2` FOREIGN KEY (`id_depart_in`) REFERENCES `#departaments`(`id_depart`); |
Lets start from the facts, this is not a bug. InnoDB internally uses foreign keys named with <table_name>ibfk<n> if no other name is provided. I strongly suggest that you try to avoid names starting with `#` and names ending with ibfk. Now the error message is really meaningless but you should see on error log something like this:
InnoDB: 1) Table rename would cause two FOREIGN KEY constraints
InnoDB: to have the same internal name in case-insensitive comparison.
InnoDB: 2) table `test`.`#departments_pos` exists in the InnoDB internal data
InnoDB: dictionary though MySQL is trying to rename table `test`.`#sql-4389_3` to it.
InnoDB: Have you deleted the .frm file and not used DROP TABLE?
InnoDB: You can look for further help from
InnoDB: http://dev.mysql.com/doc/refman/5.6/en/innodb-troubleshooting.html
InnoDB: If table `test`.`#departments_pos` is a temporary table #sql..., then it can be that
InnoDB: there are still queries running on the table, and it will be
InnoDB: dropped automatically when the queries end.
InnoDB: You can drop the orphaned table inside InnoDB by
InnoDB: creating an InnoDB table with the same name in another
InnoDB: database and copying the .frm file to the current database.
InnoDB: Then MySQL thinks the table exists, and DROP TABLE will
InnoDB: succeed.
In above examples you have named your foreign key constraint so that alter will fail because there would be two identical foreign key names in InnoDB data dictionary.
I will try to add more clearer error message so that show warnings after failed alter table would return more information why alter really failed.