Skip to content

Commit f13005c

Browse files
nacarvalhoHery Ramilison
authored andcommitted
BUG#24818604: MYSQLD CRASHES WHILE STARTING GROUP REPLICATION FOR A NODE IN RECOVERY PROCESS
During BUG#24818604: MYSQLD CRASHES WHILE STARTING GROUP REPLICATION FOR A NODE IN RECOVERY PROCESS analysis, three issues were found: 1) Foreign keys were not being ignored when foreign_key_checks == 0 That was fixed on BUG#24916351: GR KEY GENERATION FOR FOREIGN KEY SHOULD BE IGNORED IF PARENT IS NOT YET CREATED 2) Foreign keys referenced_key_name could be NULL when a DELETE on a child table was executed before accessing the parent, like just after server start. That was fixed on BUG#25126722 FOREIGN KEY CONSTRAINT NAME IS NULL IN INFORMATION_SCHEMA AFTER RESTART 3) A DELETE on child table after the parent table was dropped using foreign_key_checks= 0, is making referenced_key_name NULL and consequently crashing the server. This patch solves issue 3), by skipping foreign keys inclusion on transaction write set if referenced_key_name is NULL, since this, after issue 1) and 2) fix, means that the parent table does not exist and there is no foreign key constraint. (cherry picked from commit 3160ccf71a0b6fd1d5d87d4ce63c9477f5626e44)
1 parent f1beb8b commit f13005c

File tree

4 files changed

+53
-1
lines changed

4 files changed

+53
-1
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
call mtr.add_suppression("InnoDB: Foreign Key referenced table test.t1 not found for foreign table test.t2");
2+
SET @saved_foreign_key_checks= @@session.foreign_key_checks;
3+
SET @@session.foreign_key_checks= 1;
4+
CREATE TABLE t1 (c1 INT PRIMARY KEY);
5+
CREATE TABLE t2 (c1 INT PRIMARY KEY, FOREIGN KEY (c1) REFERENCES t1(c1));
6+
INSERT INTO t1 VALUES (1);
7+
INSERT INTO t2 VALUES (1);
8+
SET @@session.foreign_key_checks= 0;
9+
DROP TABLE t1;
10+
SET @@session.foreign_key_checks= 1;
11+
DELETE FROM t2 WHERE c1=1;
12+
DROP TABLE t2;
13+
SET @@session.foreign_key_checks= @saved_foreign_key_checks;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--transaction-write-set-extraction=XXHASH64
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
################################################################################
2+
# Validate that when a DELETE operation is done on a child table, after the
3+
# parent table was dropped using foreign_key_checks= 0, the server does not crash.
4+
#
5+
# Test:
6+
# 0. Create a parent and child tables.
7+
# 1. Drop parent table with foreign_key_checks= 0.
8+
# 2. Delete a row from the child table with foreign_key_checks= 1.
9+
################################################################################
10+
--source include/have_binlog_format_row.inc
11+
12+
call mtr.add_suppression("InnoDB: Foreign Key referenced table test.t1 not found for foreign table test.t2");
13+
14+
SET @saved_foreign_key_checks= @@session.foreign_key_checks;
15+
SET @@session.foreign_key_checks= 1;
16+
17+
CREATE TABLE t1 (c1 INT PRIMARY KEY);
18+
CREATE TABLE t2 (c1 INT PRIMARY KEY, FOREIGN KEY (c1) REFERENCES t1(c1));
19+
20+
INSERT INTO t1 VALUES (1);
21+
INSERT INTO t2 VALUES (1);
22+
23+
SET @@session.foreign_key_checks= 0;
24+
DROP TABLE t1;
25+
SET @@session.foreign_key_checks= 1;
26+
27+
DELETE FROM t2 WHERE c1=1;
28+
29+
DROP TABLE t2;
30+
31+
SET @@session.foreign_key_checks= @saved_foreign_key_checks;

sql/rpl_write_set_handler.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,14 @@ void check_foreign_key(TABLE *table, THD *thd,
106106
LEX_STRING *f_info;
107107
while ((f_key_info=foreign_key_iterator++))
108108
{
109+
/*
110+
If referenced_key_name is NULL it means that the parent table
111+
was dropped using foreign_key_checks= 0, on that case we
112+
cannot check foreign key and need to skip it.
113+
*/
114+
if (f_key_info->referenced_key_name == NULL)
115+
continue;
116+
109117
std::string temporary_pke;
110118
List_iterator_fast<LEX_STRING> foreign_fields_iterator(f_key_info->foreign_fields);
111119

@@ -125,7 +133,6 @@ void check_foreign_key(TABLE *table, THD *thd,
125133
length_table, MYF(0));
126134
char *char_length_table= my_safe_itoa(10, length_table, &buffer_table[length_table-1]);
127135

128-
DBUG_ASSERT(f_key_info->referenced_key_name);
129136
/*
130137
Prefix the hash keys with the referenced index name.
131138
*/

0 commit comments

Comments
 (0)