| Bug #69707 | Adding "_ibfk_" foreign key "Table XXX already exists" | ||
|---|---|---|---|
| Submitted: | 10 Jul 2013 4:47 | Modified: | 12 Aug 2013 11:35 |
| Reporter: | Ryan Kenney | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: InnoDB storage engine | Severity: | S2 (Serious) |
| Version: | 5.5.32 Win64 | OS: | Windows (7) |
| Assigned to: | CPU Architecture: | Any | |
[10 Jul 2013 4:47]
Ryan Kenney
[10 Jul 2013 5:06]
MySQL Verification Team
Hello Ryan, Thank you for the bug report. Verified as described on 5.5.32 version. Thanks, Umesh
[10 Jul 2013 5:07]
MySQL Verification Team
// 5.5.32 - affected
node1 [localhost] {msandbox} (my_test_db) > select version();
+------------+
| version() |
+------------+
| 5.5.32-log |
+------------+
1 row in set (0.00 sec)
node1 [localhost] {msandbox} ((none)) > DROP DATABASE IF EXISTS my_test_db;
Query OK, 0 rows affected, 1 warning (0.00 sec)
node1 [localhost] {msandbox} ((none)) > CREATE DATABASE my_test_db;
Query OK, 1 row affected (0.00 sec)
node1 [localhost] {msandbox} ((none)) > USE my_test_db;
Database changed
node1 [localhost] {msandbox} (my_test_db) > CREATE TABLE IF NOT EXISTS `door` (
-> `key` int(10) unsigned NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY(`key`)
-> ) ENGINE=INNODB;
CREATE TABLE IF NOT EXISTS `window` (
`key` int(10) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY(`key`)
) ENGINE=INNODB;Query OK, 0 rows affected (0.10 sec)
node1 [localhost] {msandbox} (my_test_db) > CREATE TABLE IF NOT EXISTS `window` (
-> `key` int(10) unsigned NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY(`key`)
-> ) ENGINE=INNODB;
Query OK, 0 rows affected (0.25 sec)
node1 [localhost] {msandbox} (my_test_db) > CREATE TABLE `house` (
-> `key` int(10) unsigned NOT NULL AUTO_INCREMENT,
-> `door` int(10) unsigned DEFAULT NULL,
-> `window` int(10) unsigned DEFAULT NULL,
-> PRIMARY KEY (`key`),
-> KEY `my_arbitrarily_named_constraint_ibfk_1` (`door`),
-> KEY `other_arbitrarily_named_constraint_ibfk_1` (`window`),
-> CONSTRAINT `my_arbitrarily_named_constraint_ibfk_1` FOREIGN KEY (`door`) REFERENCES `door` (`key`) ON UPDATE CASCADE,
-> CONSTRAINT `house_ibfk_1` FOREIGN KEY (`window`) REFERENCES `window` (`key`) ON DELETE SET NULL
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE house DROP FOREIGN KEY `my_arbitrarily_named_constraint_ibfk_1`;
ALTER TABLE house ADD CONSTRAINT `my_arbitrarily_named_constraint_ibfk_1` FOREIGN KEY (`door`) REFERENCES `door` (`key`) ON DELETE CASCADE ON UPDATE CASCADE;Query OK, 0 rows affected (0.23 sec)
node1 [localhost] {msandbox} (my_test_db) > ALTER TABLE house DROP FOREIGN KEY `my_arbitrarily_named_constraint_ibfk_1`;
Query OK, 0 rows affected (0.23 sec)
Records: 0 Duplicates: 0 Warnings: 0
node1 [localhost] {msandbox} (my_test_db) > ALTER TABLE house ADD CONSTRAINT `my_arbitrarily_named_constraint_ibfk_1` FOREIGN KEY (`door`) REFERENCES `door` (`key`) ON DELETE CASCADE ON UPDATE CASCADE;
ERROR 1050 (42S01): Table './my_test_db/house' already exists
node1 [localhost] {msandbox} (my_test_db) >
// 5.6.12 not affected
mysql> select version();
+------------------+
| version() |
+------------------+
| 5.6.12-debug-log |
+------------------+
1 row in set (0.00 sec)
mysql> DROP DATABASE IF EXISTS my_test_db;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> CREATE DATABASE my_test_db;
Query OK, 1 row affected (0.00 sec)
mysql> USE my_test_db;
Database changed
mysql> CREATE TABLE IF NOT EXISTS `door` (
-> `key` int(10) unsigned NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY(`key`)
-> ) ENGINE=INNODB;
Query OK, 0 rows affected (0.33 sec)
mysql> CREATE TABLE IF NOT EXISTS `window` (
-> `key` int(10) unsigned NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY(`key`)
-> ) ENGINE=INNODB;
Query OK, 0 rows affected (0.11 sec)
mysql> CREATE TABLE `house` (
-> `key` int(10) unsigned NOT NULL AUTO_INCREMENT,
-> `door` int(10) unsigned DEFAULT NULL,
-> `window` int(10) unsigned DEFAULT NULL,
-> PRIMARY KEY (`key`),
-> KEY `my_arbitrarily_named_constraint_ibfk_1` (`door`),
-> KEY `other_arbitrarily_named_constraint_ibfk_1` (`window`),
-> CONSTRAINT `my_arbitrarily_named_constraint_ibfk_1` FOREIGN KEY (`door`) REFERENCES `door` (`key`) ON UPDATE CASCADE,
-> CONSTRAINT `house_ibfk_1` FOREIGN KEY (`window`) REFERENCES `window` (`key`) ON DELETE SET NULL
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.22 sec)
mysql> ALTER TABLE house DROP FOREIGN KEY `my_arbitrarily_named_constraint_ibfk_1`;
Query OK, 0 rows affected (0.15 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE house ADD CONSTRAINT `my_arbitrarily_named_constraint_ibfk_1` FOREIGN KEY (`door`) REFERENCES `door` (`key`) ON DELETE CASCADE ON UPDATE CASCADE;
Query OK, 0 rows affected (0.66 sec)
Records: 0 Duplicates: 0 Warnings: 0
[10 Jul 2013 5:22]
MySQL Verification Team
Bug #69699 marked as duplicate of this one.
[11 Jul 2013 8:06]
Cyril Scetbon
fixed in 5.6.12
[11 Jul 2013 17:28]
Ryan Kenney
Here's the workaround I ended up applying to our software so that it can be installed on a server running 5.5.32 without incident. The gist is that I forced all foreign keys to use the standard naming convention (e.g. "<table name>_ibfk_<index>"). When you do this, 5.5.32 works just like previous versions. It's not completely obvious from my example above, but some of the odd key naming was a result of earlier scripts doing wonky things due to an issue similar to #69693. In the end my solution was to: * Modify all historical scripts to use standardized foreign key names * Add DB tasks that drop/re-add any non-standard foreign keys Queries to the following tables let us identify the state of things, but I didn't figure out how to query these tables and then apply the fixes using pure sql, so I ended up using jdbc to solve the problem, which is fine for our system. * INFORMATION_SCHEMA.TABLE_CONSTRAINTS * INFORMATION_SCHEMA.KEY_COLUMN_USAGE
[12 Aug 2013 11:35]
Bugs System
Added this bug number to the existing changelog entry for Bug #17076737. Thank you for the bug report.
[26 Jan 2017 13:57]
Daniel Price
Posted by developer: The changelog text was revised as follows: "Adding a foreign key with a constraint name that included the string _ibfk_ caused InnoDB to create a duplicate constraint with a generated internal name. The generated internal name could also collide with an existing user-defined constraint of the same name, causing a duplicate key error."
[27 Jan 2017 17:19]
Daniel Price
Posted by developer: The following related updates were made to the MySQL reference manual: https://dev.mysql.com/doc/refman/5.7/en/rename-table.html RENAME TABLE changes internally generated foreign key constraint names and user-defined foreign key constraint names that contain the string “tbl_name_ibfk_” to reflect the new table name. InnoDB interprets foreign key constraint names that contain the string “tbl_name_ibfk_” as internally generated names. https://dev.mysql.com/doc/refman/5.7/en/alter-table.html ALTER TABLE tbl_name RENAME new_tbl_name changes internally generated foreign key constraint names and user-defined foreign key constraint names that contain the string “tbl_name_ibfk_” to reflect the new table name. InnoDB interprets foreign key constraint names that contain the string “tbl_name_ibfk_” as internally generated names.
