mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
MDEV-28317 Assertion failures in row_undo_mod on recovery
Starting with 10.3, an assertion would fail on the rollback of
a recovered incomplete transaction if a table definition violates
a FOREIGN KEY constraint.
DICT_ERR_IGNORE_RECOVER_LOCK: Include also DICT_ERR_IGNORE_FK_NOKEY
so that trx_resurrect_table_locks() will be able to load
table definitions and resurrect IX locks. Previously, if the
FOREIGN KEY constraints of a table were incomplete, the table
would fail to load until rollback, and in 10.3 or later an assertion
would fail that the rollback was not protected by a table IX lock.
Thanks to commit 9de2e60d74
there
will be no problems to enforce subsequent FOREIGN KEY operations
even though a table with invalid REFERENCES clause was loaded.
This commit is contained in:
@ -137,6 +137,33 @@ SELECT unique_constraint_name FROM information_schema.referential_constraints
|
|||||||
WHERE table_name = 't2';
|
WHERE table_name = 't2';
|
||||||
unique_constraint_name
|
unique_constraint_name
|
||||||
PRIMARY
|
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 @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
|
||||||
SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
|
SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
|
||||||
SELECT unique_constraint_name FROM information_schema.referential_constraints
|
SELECT unique_constraint_name FROM information_schema.referential_constraints
|
||||||
|
@ -102,7 +102,41 @@ INSERT INTO t2 VALUES (1);
|
|||||||
SELECT unique_constraint_name FROM information_schema.referential_constraints
|
SELECT unique_constraint_name FROM information_schema.referential_constraints
|
||||||
WHERE table_name = 't2';
|
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
|
--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 @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
|
||||||
SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
|
SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
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
|
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
|
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
|
DICT_ERR_IGNORE_INDEX_ROOT = 2, /*!< ignore error if index root
|
||||||
page is FIL_NULL or incorrect value */
|
page is FIL_NULL or incorrect value */
|
||||||
DICT_ERR_IGNORE_CORRUPT = 4, /*!< skip corrupted indexes */
|
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
|
/*!< Used when recovering table locks
|
||||||
for resurrected transactions.
|
for resurrected transactions.
|
||||||
Silently load a missing
|
Silently load a missing
|
||||||
|
Reference in New Issue
Block a user