pt-online-schema-change fails with self-referential foreign key
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Percona Toolkit moved to https://jira.percona.com/projects/PT |
Fix Released
|
High
|
Carlos Salguero |
Bug Description
I have an existing table with the following schema:
CREATE TABLE `ConfigData` (
`primaryKey` bigint(20) NOT NULL AUTO_INCREMENT,
`id` varchar(36) DEFAULT NULL,
`version` int(11) NOT NULL,
`createdBy` varchar(36) DEFAULT NULL,
`createdDate` datetime DEFAULT NULL,
`lastModifiedBy` varchar(36) DEFAULT NULL,
`lastModified
`tenantId` varchar(36) DEFAULT NULL,
PRIMARY KEY (`primaryKey`),
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Then I run the follwing ALTER tables throught pt-online-
- ADD COLUMN `parentEntity_
- ADD KEY `parentEntityPr
- ADD CONSTRAINT `parentEntityFK` FOREIGN KEY (`parentEntity_
pt-online-
CREATE TABLE `ConfigData` (
`primaryKey` bigint(20) NOT NULL AUTO_INCREMENT,
`id` varchar(36) DEFAULT NULL,
`version` int(11) NOT NULL,
`createdBy` varchar(36) DEFAULT NULL,
`createdDate` datetime DEFAULT NULL,
`lastModifiedBy` varchar(36) DEFAULT NULL,
`lastModified
`tenantId` varchar(36) DEFAULT NULL,
`parentEntity
PRIMARY KEY (`primaryKey`),
UNIQUE KEY `id` (`id`),
KEY `parentEntityPr
CONSTRAINT `parentEntityFK` FOREIGN KEY (`parentEntity_
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
As you can see the problem with the parentEntityFK which references _ConfigData_old. The tool fails when trying to drop this table due to foreign key problems.
Tool/Server Versions:
- 5.6.19-
- pt-online-
DEBUG output for ADD CONSTRAINT `parentEntityFK` FOREIGN KEY is attached.
Changed in percona-toolkit: | |
status: | New → Confirmed |
Changed in percona-toolkit: | |
status: | Confirmed → Triaged |
assignee: | nobody → Frank Cizmich (frank-cizmich) |
Changed in percona-toolkit: | |
importance: | Undecided → High |
assignee: | Frank Cizmich (frank-cizmich) → Carlos Salguero (carlos-salguero) |
milestone: | none → 2.2.21 |
Changed in percona-toolkit: | |
status: | Triaged → In Progress |
Changed in percona-toolkit: | |
status: | In Progress → Fix Committed |
Changed in percona-toolkit: | |
status: | Fix Committed → Fix Released |
milestone: | 2.2.21 → 3.0.1 |
Error is verified and reproducible with the latest version 2.2.12.
Test _primaryKey` bigint(20) DEFAULT NULL, imaryKey` (`parentEntity_ primaryKey` )
------------
CREATE TABLE `ConfigData` (
`primaryKey` bigint(20) NOT NULL AUTO_INCREMENT,
`id` varchar(36) DEFAULT NULL,
`parentEntity
PRIMARY KEY (`primaryKey`),
KEY `parentEntityPr
)ENGINE=InnoDB DEFAULT CHARSET=latin1;
# ./pt-online- schema- change --execute --alter "ADD CONSTRAINT parentEntityFK FOREIGN KEY (parentEntity_ primaryKey) REFERENCES ConfigData (primaryKey)" D=test,t=ConfigData `_ConfigData_ old`"] at ./pt-online- schema- change line 9328.
...
2014-11-21T17:01:02 Error dropping the old table: DBD::mysql::db do failed: Cannot delete or update a parent row: a foreign key constraint fails [for Statement "DROP TABLE IF EXISTS `test`.
Workaround ------- ------- ---
-------
When the tool runs, it creates a new table named _<table_name>_new and run the alter on the new table. Thus the referential constraint should really be created on this new table instead of the original one. The following command works:
# ./pt-online- schema- change --execute --alter "ADD CONSTRAINT parentEntityFK FOREIGN KEY (parentEntity_ primaryKey) REFERENCES _ConfigData_new (primaryKey)" D=test,t=ConfigData
Suggested Fix ------- ------- ---
-------
Replace table name in self-referential FK reference to the new table name.