Bug #89441 Foreign keys constraints ignored after RENAME TABLE
Submitted: 26 Jan 2018 19:20 Modified: 1 Nov 2018 13:21
Reporter: Carlos Salguero Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: DDL Severity:S1 (Critical)
Version:8.0.4-rc, 8.0.2-dmr, 8.0.3-rc OS:Any
Assigned to: CPU Architecture:Any

[26 Jan 2018 19:20] Carlos Salguero
Description:
While I was testing Percona online-schema-change, I found an error with FK constraints.

On a high level, what the tool does is this:
1. Create a tmp table
2. Copy all rows from the original one to the new tmp table
3. Disable FK checks
4. Drop old table
5. Rename tmp to the original name
6. Re-enable FKs.

After that, FKs constraints are still being considered by MySQL 5.7, but in MySQL 8, FKs constraints are ignored after the rename, even when they still exist in INFORMATION_SCHEMA.INNODB_FOREIGN and INFORMATION_SCHEMA.INNODB_FOREIGN_COLS.

The last DELETE fails in MySQL 5.7 due to the FK constraints, but in MySQL 8.0.4-rc, the row with country_id = 1 is being deleted since FK constraints are being ignored. 

How to repeat:
CREATE DATABASE pt_osc;
-- Query OK, 1 row affected (0.01 sec)

USE pt_osc;
-- Database changed

SET foreign_key_checks=0;
-- Query OK, 0 rows affected (0.01 sec)

CREATE TABLE `country` (
       `country_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
       `country` varchar(50) NOT NULL,
       `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
       PRIMARY KEY (`country_id`)
     ) ENGINE=InnoDB;
-- Query OK, 0 rows affected (0.01 sec)

CREATE TABLE `city` (
       `city_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
       `city` varchar(50) NOT NULL,
       `country_id` smallint(5) unsigned NOT NULL,
       `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
       PRIMARY KEY (`city_id`),
       KEY `idx_fk_country_id` (`country_id`),
       CONSTRAINT `fk_city_country` FOREIGN KEY (`country_id`) REFERENCES `country` (`country_id`) ON UPDATE CASCADE
     ) ENGINE=InnoDB;
-- Query OK, 0 rows affected (0.01 sec)

CREATE TABLE `address` (
       `address_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
       `address` varchar(50) NOT NULL,
       `city_id` smallint(5) unsigned NOT NULL,
       `postal_code` varchar(10) DEFAULT NULL,
       `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
       PRIMARY KEY (`address_id`),
       KEY `idx_fk_city_id` (`city_id`),
       CONSTRAINT `fk_address_city` FOREIGN KEY (`city_id`) REFERENCES `city` (`city_id`) ON UPDATE CASCADE
     ) ENGINE=InnoDB;
-- Query OK, 0 rows affected (0.02 sec)

INSERT INTO pt_osc.country (`country_id`, `country`) VALUES
       (1, 'Canada'),
       (2, 'USA'),
       (3, 'Mexico'),
       (4, 'France'),
       (5, 'Spain');
-- Query OK, 5 rows affected (0.00 sec)
-- Records: 5  Duplicates: 0  Warnings: 0

INSERT INTO pt_osc.city (`city_id`, `city`, `country_id`) VALUES
       (1, 'Montral', 1),
       (2, 'New York', 2),
       (3, 'Durango',  3),
       (4, 'Paris',    4),
       (5, 'Madrid',   5);
-- Query OK, 5 rows affected (0.00 sec)
-- Records: 5  Duplicates: 0  Warnings: 0

INSERT INTO pt_osc.address (`address_id`, `address`, `city_id`, `postal_code`) VALUES
       (1, 'addy 1', 1, '10000'),
       (2, 'addy 2', 2, '20000'),
       (3, 'addy 3', 3, '30000'),
       (4, 'addy 4', 4, '40000'),
       (5, 'addy 5', 5, '50000');
-- Query OK, 5 rows affected (0.01 sec)
-- Records: 5  Duplicates: 0  Warnings: 0

SET foreign_key_checks=1;
-- Query OK, 0 rows affected (0.00 sec)

DELETE FROM country WHERE country_id =1;
-- ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`pt_osc`.`city`, CONSTRAINT `fk_city_country` FOREIGN KEY (`country_id`) REFERENCES `country` (`country_id`) ON UPDATE CASCADE)

SELECT * FROM INFORMATION_SCHEMA.INNODB_FOREIGN;
-- +------------------------+----------------+----------------+--------+------+
-- | ID                     | FOR_NAME       | REF_NAME       | N_COLS | TYPE |
-- +------------------------+----------------+----------------+--------+------+
-- | test/fk_city_country   | test/city      | test/country   |      1 |    0 |
-- | pt_osc/fk_city_country | pt_osc/city    | pt_osc/country |      1 |    0 |
-- | pt_osc/fk_address_city | pt_osc/address | pt_osc/city    |      1 |    0 |
-- +------------------------+----------------+----------------+--------+------+
-- 3 rows in set (0.01 sec)

CREATE TABLE tmp_country LIKE country;
-- Query OK, 0 rows affected (0.01 sec)

INSERT INTO tmp_country SELECT * FROM country;
-- Query OK, 5 rows affected (0.00 sec)
-- Records: 5  Duplicates: 0  Warnings: 0

SET foreign_key_checks=0;
-- Query OK, 0 rows affected (0.00 sec)

DROP TABLE country;
-- Query OK, 0 rows affected (0.00 sec)

RENAME TABLE tmp_country TO country;
-- Query OK, 0 rows affected (0.01 sec)

SET foreign_key_checks=1;
-- Query OK, 0 rows affected (0.00 sec)

DELETE FROM country WHERE country_id =1;
-- Query OK, 1 row affected (0.00 sec)

SELECT * FROM INFORMATION_SCHEMA.INNODB_FOREIGN;
-- +------------------------+----------------+----------------+--------+------+
-- | ID                     | FOR_NAME       | REF_NAME       | N_COLS | TYPE |
-- +------------------------+----------------+----------------+--------+------+
-- | test/fk_city_country   | test/city      | test/country   |      1 |    0 |
-- | pt_osc/fk_city_country | pt_osc/city    | pt_osc/country |      1 |    0 |
-- | pt_osc/fk_address_city | pt_osc/address | pt_osc/city    |      1 |    0 |
-- +------------------------+----------------+----------------+--------+------+
-- 3 rows in set (0.00 sec)

SELECT * FROM INFORMATION_SCHEMA.INNODB_FOREIGN_COLS;
-- +------------------------+--------------+--------------+-----+
-- | ID                     | FOR_COL_NAME | REF_COL_NAME | POS |
-- +------------------------+--------------+--------------+-----+
-- | test/fk_city_country   | country_id   | country_id   |   1 |
-- | pt_osc/fk_city_country | country_id   | country_id   |   1 |
-- | pt_osc/fk_address_city | city_id      | city_id      |   1 |
-- +------------------------+--------------+--------------+-----+
-- 3 rows in set (0.00 sec)
[29 Jan 2018 5:45] MySQL Verification Team
Hello Carlos,

Thank you for the report and test case.
Confirmed that this is observed since 8.0.2-dmr.

Thanks,
Umesh
[13 Jun 2018 19:27] Carlos Salguero
Hi, 

Is there any news about this bug?
[4 Oct 2018 0:48] Bin Su
Posted by developer:
 
As mentioned in the email named "Fixing bug #27453180 "FOREIGN KEYS CONSTRAINTS IGNORED AFTER RENAME TABLE".", re-assign this to Anna, thanks Anna.
[1 Nov 2018 13:21] Daniel Price
Posted by developer:
 
Fixed as of the upcoming 8.0.14 release, and here's the changelog entry:

Foreign key constraints were ignored after a RENAME TABLE operation.
[7 Jun 2023 18:17] Muhammad Usman
Hi Team, 

We are getting below error 

SELECT /*!40001 SQL_NO_CACHE */ `mt_message_id` FROM `smpp_server`.`mt_message` FORCE INDEX(`PRIMARY`) WHERE ((`mt_message_id` >= ?)) AND (mt_message_id > '4118849778') ORDER BY `mt_message_id` LIMIT ?, 2 /*next chunk boundary*/
2023-06-07T20:40:41 Copied rows OK.
2023-06-07T20:40:41 Max rows for the rebuild_constraints method: 4000
Determining the method to update foreign keys...
2023-06-07T20:40:41   `smpp_server`.`mo_message`: too many rows: 20455781; must use drop_swap
--alter-foreign-keys-method=drop_swap doesn't work with MySQL 8.0+
See https://bugs.mysql.com/bug.php?id=89441
2023-06-07T20:40:41 Dropping triggers...
DROP TRIGGER IF EXISTS `smpp_server`.`pt_osc_smpp_server_mt_message_del`
DROP TRIGGER IF EXISTS `smpp_server`.`pt_osc_smpp_server_mt_message_upd`
DROP TRIGGER IF EXISTS `smpp_server`.`pt_osc_smpp_server_mt_message_ins`
2023-06-07T20:40:41 Dropped triggers OK.
Not dropping the new table `smpp_server`.`_mt_message_new` because --swap-tables failed.  To drop the new table, execute:
DROP TABLE IF EXISTS `smpp_server`.`_mt_message_new`;
`smpp_server`.`mt_message` was not altered.
"INFO-690647788.log" 107L, 10935C   

Our Mysql version is 

mysql  Ver 8.0.30-22 for Linux on x86_64 (Percona Server (GPL), Release 22, Revision 7e301439b65)

Please help to fix it. Thank you. 

BR//Muhammad Usman
[7 Jun 2023 18:19] Muhammad Usman
Subscribing to email updates on this bug report.
[7 Jun 2023 18:50] Muhammad Usman
And Percona Toolkit version is 

package Percona::Toolkit;

our $VERSION = '3.3.1';