pt-online-schema-change foreign key
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Percona Toolkit moved to https://jira.percona.com/projects/PT |
Confirmed
|
Undecided
|
Unassigned |
Bug Description
When you run pt-osc and it fails, in some cases the _new_table file will still exist (mind the underscore file).
The pt-osc knows that and actually creates __new_table the next run. (That's why we love percona toolkit!)
A similar mechanism happens when you have foreign keys, as they are unique in name as well.
An underscore is added to the foreign key name when you create such table.
HOWEVER, when that _new_table is still there, the foreign key name with the underscore still exists. pt-osc does not try to find a unique foreign key name by adding for example another underscore.
In the end you get a very weird error 121 which actually means that there's a duplicate FK name.
Please talk to me if you need a test. As it's quite late, I have no energy left to perform tests, apologies! :)
Verified.
mysql> show create table test \G ******* ******* ****** 1. row ******* ******* ******* ******
*******
Table: test
Create Table: CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> show create table test_child \G ******* ******* ****** 1. row ******* ******* ******* ******
*******
Table: test_child
Create Table: CREATE TABLE `test_child` (
`id` int(11) DEFAULT NULL,
`parent_id` int(11) DEFAULT NULL,
KEY `par_ind` (`parent_id`),
KEY `id` (`id`),
CONSTRAINT `test_child_ibfk_1` FOREIGN KEY (`id`) REFERENCES `test` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> schema- change --no-drop-new-table --alter "ADD COLUMN c2 INT" D=nil,t=test_child --execute localdomain has slaves. foreign_ keys, 10, 1 test_child` ... _test_child_ new` OK. _test_child_ new` because --no-drop-new-table was specified. To drop the new table, execute: _test_child_ new`; _test_child_ new` does not have a PRIMARY KEY or a unique index which is required for the DELETE trigger.
[root@localhost ~]# pt-online-
No slaves found. See --recursion-method if host localhost.
Not checking slave lag because no slaves were found and --check-slave-lag was not specified.
Operation, tries, wait:
copy_rows, 10, 0.25
create_triggers, 10, 1
drop_triggers, 10, 1
swap_tables, 10, 1
update_
Altering `nil`.`
Creating new table...
Created new table nil._test_child_new OK.
Altering new table...
Altered `nil`.`
Not dropping the new table `nil`.`
DROP TABLE IF EXISTS `nil`.`
`nil`.`test_child` was not altered.
The new table `nil`.`
[root@localhost ~]#
[root@localhost ~]# ls -al /var/lib/mysql/nil/ schema- change --no-drop-new-table --alter "ADD COLUMN c2 INT" D=nil,t=test_child --execute localdomain has slaves. foreign_ keys, 10, 1 test_child` ... __test_ child_new` (
total 508
drwx------. 2 mysql mysql 4096 Mar 10 11:28 .
drwxrwxrwx. 6 mysql mysql 4096 Mar 10 11:00 ..
-rw-rw----. 1 mysql mysql 65 Mar 10 11:00 db.opt
-rw-rw----. 1 mysql mysql 8586 Mar 10 11:25 nil_tab.frm
-rw-rw----. 1 mysql mysql 98304 Mar 10 11:25 nil_tab.ibd
-rw-rw----. 1 mysql mysql 8596 Mar 10 11:02 test_child.frm
-rw-rw----. 1 mysql mysql 131072 Mar 10 11:12 test_child.ibd
-rw-rw----. 1 mysql mysql 8622 Mar 10 11:28 _test_child_new.frm
-rw-rw----. 1 mysql mysql 131072 Mar 10 11:28 _test_child_new.ibd
-rw-rw----. 1 mysql mysql 8586 Mar 10 11:01 test.frm
-rw-rw----. 1 mysql mysql 98304 Mar 10 11:11 test.ibd
[root@localhost ~]#
[root@localhost ~]# pt-online-
No slaves found. See --recursion-method if host localhost.
Not checking slave lag because no slaves were found and --check-slave-lag was not specified.
Operation, tries, wait:
copy_rows, 10, 0.25
create_triggers, 10, 1
drop_triggers, 10, 1
swap_tables, 10, 1
update_
Altering `nil`.`
Creating new table...
`nil`.`test_child` was not altered.
Error creating new table: DBD::mysql::db do failed: Can't write; duplicate key in table '__test_child_new' [for Statement "CREATE TABLE `nil`.`
`id` int(11) DEFAULT NULL,
`parent_id` int(11) DEFAUL...