diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index d6420118f34..dc958724fef 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -137,6 +137,33 @@ SELECT unique_constraint_name FROM information_schema.referential_constraints WHERE table_name = 't2'; unique_constraint_name PRIMARY +# +# MDEV-28317 Assertion failure on rollback of FOREIGN KEY operation +# +SET foreign_key_checks=0; +CREATE TABLE parent(a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE child(a INT,FOREIGN KEY(a) REFERENCES parent(a) ON DELETE CASCADE) +ENGINE=InnoDB; +INSERT INTO child VALUES(1); +ALTER TABLE child DROP INDEX a; +connect incomplete, localhost, root,,; +BEGIN; +DELETE FROM child; +connection default; +INSERT INTO parent SET a=0; +FLUSH TABLES; +disconnect incomplete; +INSERT INTO child SET a=0; +INSERT INTO child SET a=1; +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `parent` (`a`) ON DELETE CASCADE) +DELETE FROM parent; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `parent` (`a`) ON DELETE CASCADE) +ALTER TABLE child ADD INDEX(a); +DELETE FROM parent; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `parent` (`a`) ON DELETE CASCADE) +ALTER TABLE child FORCE; +DELETE FROM parent; +DROP TABLE child,parent; SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; SELECT unique_constraint_name FROM information_schema.referential_constraints diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index 1d4e5fd9d2a..af23dbdbb28 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -102,7 +102,41 @@ INSERT INTO t2 VALUES (1); SELECT unique_constraint_name FROM information_schema.referential_constraints WHERE table_name = 't2'; +--echo # +--echo # MDEV-28317 Assertion failure on rollback of FOREIGN KEY operation +--echo # + +SET foreign_key_checks=0; +CREATE TABLE parent(a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE child(a INT,FOREIGN KEY(a) REFERENCES parent(a) ON DELETE CASCADE) +ENGINE=InnoDB; +INSERT INTO child VALUES(1); +ALTER TABLE child DROP INDEX a; + +connect(incomplete, localhost, root,,); +BEGIN; +DELETE FROM child; + +connection default; +INSERT INTO parent SET a=0; +FLUSH TABLES; + +--let $shutdown_timeout=0 --source include/restart_mysqld.inc +--let $shutdown_timeout= +disconnect incomplete; + +INSERT INTO child SET a=0; +--error ER_NO_REFERENCED_ROW_2 +INSERT INTO child SET a=1; +--error ER_ROW_IS_REFERENCED_2 +DELETE FROM parent; +ALTER TABLE child ADD INDEX(a); +--error ER_ROW_IS_REFERENCED_2 +DELETE FROM parent; +ALTER TABLE child FORCE; +DELETE FROM parent; +DROP TABLE child,parent; SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; diff --git a/storage/innobase/include/dict0types.h b/storage/innobase/include/dict0types.h index bea08f398de..04c8b163b14 100644 --- a/storage/innobase/include/dict0types.h +++ b/storage/innobase/include/dict0types.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2019, MariaDB Corporation. +Copyright (c) 2013, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -64,7 +64,7 @@ enum dict_err_ignore_t { DICT_ERR_IGNORE_INDEX_ROOT = 2, /*!< ignore error if index root page is FIL_NULL or incorrect value */ DICT_ERR_IGNORE_CORRUPT = 4, /*!< skip corrupted indexes */ - DICT_ERR_IGNORE_RECOVER_LOCK = 8, + DICT_ERR_IGNORE_RECOVER_LOCK = 8 | DICT_ERR_IGNORE_FK_NOKEY, /*!< Used when recovering table locks for resurrected transactions. Silently load a missing