Skip to content

Commit f915b1c

Browse files
committed
MDEV-36923 : Add warning messages for applier FK failures
Add warning messages if applier write set execution fails because of foreign key constraint error. Warnings are printed by default and can be disabled using SET GLOBAL wsrep_mode=APPLIER_DISABLE_FK_WARNINGS.
1 parent 9f64b29 commit f915b1c

20 files changed

+350
-21
lines changed

include/mysql/service_wsrep.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ enum Wsrep_service_key_type
1414
#else
1515

1616
/* Copyright (c) 2015, 2020, MariaDB Corporation Ab
17-
2018 Codership Oy <[email protected]>
17+
2018, 2025, Codership Oy <[email protected]>
1818
1919
This program is free software; you can redistribute it and/or modify
2020
it under the terms of the GNU General Public License as published by
@@ -96,6 +96,7 @@ extern struct wsrep_service_st {
9696
void (*wsrep_thd_kill_UNLOCK_func)(const MYSQL_THD thd);
9797
void (*wsrep_thd_set_wsrep_PA_unsafe_func)(MYSQL_THD thd);
9898
uint32 (*wsrep_get_domain_id_func)();
99+
my_bool (*wsrep_applier_log_warnings)(const MYSQL_THD thd, my_bool err);
99100
} *wsrep_service;
100101

101102
#define MYSQL_SERVICE_WSREP_INCLUDED
@@ -146,6 +147,7 @@ extern struct wsrep_service_st {
146147
#define wsrep_report_bf_lock_wait(T,I) wsrep_service->wsrep_report_bf_lock_wait(T,I)
147148
#define wsrep_thd_set_PA_unsafe(T) wsrep_service->wsrep_thd_set_PA_unsafe_func(T)
148149
#define wsrep_get_domain_id(T) wsrep_service->wsrep_get_domain_id_func(T)
150+
#define wsrep_applier_log_warnings(T, B) wsrep_service->wsrep_applier_log_warnings_func(T. B)
149151
#else
150152

151153
#define MYSQL_SERVICE_WSREP_STATIC_INCLUDED
@@ -256,5 +258,6 @@ extern "C" void wsrep_report_bf_lock_wait(const THD *thd,
256258
/* declare parallel applying unsafety for the THD */
257259
extern "C" void wsrep_thd_set_PA_unsafe(MYSQL_THD thd);
258260
extern "C" uint32 wsrep_get_domain_id();
261+
extern "C" my_bool wsrep_applier_log_warnings(const MYSQL_THD thd, my_bool err);
259262
#endif
260263
#endif /* MYSQL_SERVICE_WSREP_INCLUDED */
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
connection node_2;
2+
connection node_1;
3+
CREATE TABLE parent (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
4+
CREATE TABLE child (f1 INTEGER PRIMARY KEY, p_id INTEGER,
5+
f2 INTEGER,
6+
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES parent (f1) ON DELETE CASCADE) ;
7+
CREATE TABLE grandchild (f1 INTEGER PRIMARY KEY, p_id INTEGER,
8+
f2 INTEGER,
9+
CONSTRAINT fk_2 FOREIGN KEY (p_id) REFERENCES child (p_id)) ;
10+
INSERT INTO parent VALUES (1, 1),(2,2);
11+
INSERT INTO child VALUES (1, 1, 1);
12+
connection node_1;
13+
# Make node 1 tolerate split-brain
14+
SET GLOBAL wsrep_provider_options = 'pc.ignore_sb=true';
15+
SET GLOBAL wsrep_provider_options = 'pc.weight=2';
16+
connection node_2;
17+
SET SESSION wsrep_on=OFF;
18+
DELETE FROM child WHERE f1 = 1;
19+
connection node_1;
20+
# Fails in node_2 with Foreign key warning in table: `test`.`grandchild` constraint `fk_2` failed err: adding an index entry to a child table failed.
21+
INSERT INTO grandchild VALUES (1,1,1);
22+
# Restart node_2, force SST. This is needed as node_2 is on inconsistent state
23+
connection node_2;
24+
connection node_1;
25+
connection node_2;
26+
Starting server ...
27+
include/assert_grep.inc [Foreign key warning in table: \`test\`\.\`grandchild\` constraint \`fk_2\` failed err: adding an index entry to a child table failed.]
28+
connection node_1;
29+
drop table grandchild;
30+
drop table child;
31+
drop table parent;
32+
SET GLOBAL wsrep_provider_options = 'pc.ignore_sb=false';
33+
SET GLOBAL wsrep_provider_options = 'pc.weight=1';
34+
connection node_2;
35+
call mtr.add_suppression("WSREP: Foreign key warning in table");
36+
call mtr.add_suppression("WSREP: Event 3 Write_rows_v1 apply failed");
37+
call mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on");
38+
call mtr.add_suppression("WSREP: Failed to apply write set");

mysql-test/suite/galera/r/MW-369.result

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,3 +268,44 @@ f1 p_id f2
268268
1 1 0
269269
DROP TABLE cg;
270270
DROP TABLE pg;
271+
connection node_1;
272+
CREATE TABLE `pg-` (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
273+
CREATE TABLE `cg-` (f1 INTEGER PRIMARY KEY, p_id INTEGER,
274+
f2 INTEGER,
275+
CONSTRAINT `fk_1-$$` FOREIGN KEY (p_id) REFERENCES `pg-` (f1)) ;
276+
INSERT INTO `pg-` VALUES (1, 0);
277+
INSERT INTO `pg-` VALUES (2, 0);
278+
connection node_1;
279+
SET AUTOCOMMIT=ON;
280+
START TRANSACTION;
281+
UPDATE `pg-` SET f2 = 1 WHERE f1 = 1;
282+
connection node_1a;
283+
SET SESSION wsrep_sync_wait = 0;
284+
SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb";
285+
connection node_2;
286+
INSERT INTO `cg-` VALUES (1, 1, 0);
287+
connection node_1a;
288+
SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached";
289+
connection node_1;
290+
SET SESSION DEBUG_SYNC = "wsrep_before_certification SIGNAL before_certification_reached WAIT_FOR continue_before_certification";
291+
COMMIT;
292+
connection node_1a;
293+
SET SESSION DEBUG_SYNC = "now WAIT_FOR before_certification_reached";
294+
SET SESSION DEBUG_SYNC = 'now SIGNAL continue_before_certification';
295+
SET SESSION DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb';
296+
SET GLOBAL DEBUG_DBUG = "";
297+
SET DEBUG_SYNC = 'RESET';
298+
connection node_1;
299+
call mtr.add_suppression("WSREP: Foreign key warning");
300+
# Now there should Foreign key constraint warning
301+
include/assert_grep.inc [Foreign key warning in table: \`test\`\.\`cg\` constraint \`fk_1\` failed err: Setting shared record lock to matching record in the child table failed \(Lock wait\).]
302+
connection node_2;
303+
SELECT * FROM `pg-`;
304+
f1 f2
305+
1 1
306+
2 0
307+
SELECT * FROM `cg-`;
308+
f1 p_id f2
309+
1 1 0
310+
DROP TABLE `cg-`;
311+
DROP TABLE `pg-`;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
--- /home/jan/work/mariadb/10.11/mysql-test/suite/galera/r/galera_FK_duplicate_client_insert.result
2+
+++ /home/jan/work/mariadb/10.11/mysql-test/suite/galera/r/galera_FK_duplicate_client_insert.reject
3+
@@ -380,6 +380,4 @@
4+
set debug_sync = reset;
5+
connection node_1;
6+
drop table user_session,user;
7+
-# Now there should be 10 WSREP Foreign key constraint warnings
8+
-include/assert_grep.inc [Foreign key warning in table: \`test\`\.\`user_session\` constraint \`user_session_ibfk_1\` failed err: Setting shared record lock to matching record in the child table failed \(Lock wait\).]
9+
call mtr.add_suppression("WSREP: Foreign key warning in table");

mysql-test/suite/galera/r/galera_FK_duplicate_client_insert.result

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,3 +380,6 @@ truncate user_session;
380380
set debug_sync = reset;
381381
connection node_1;
382382
drop table user_session,user;
383+
# Now there should be 10 WSREP Foreign key constraint warnings
384+
include/assert_grep.inc [Foreign key warning in table: \`test\`\.\`user_session\` constraint \`user_session_ibfk_1\` failed err: Setting shared record lock to matching record in the child table failed \(Lock wait\).]
385+
call mtr.add_suppression("WSREP: Foreign key warning in table");

mysql-test/suite/galera/r/galera_var_wsrep_mode.result

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ SET GLOBAL wsrep_mode='A';
2020
ERROR 42000: Variable 'wsrep_mode' can't be set to the value of 'A'
2121
SET GLOBAL wsrep_mode=NULL;
2222
ERROR 42000: Variable 'wsrep_mode' can't be set to the value of 'NULL'
23-
SET GLOBAL wsrep_mode=128;
24-
ERROR 42000: Variable 'wsrep_mode' can't be set to the value of '128'
23+
SET GLOBAL wsrep_mode=256;
24+
ERROR 42000: Variable 'wsrep_mode' can't be set to the value of '256'
2525
SET GLOBAL wsrep_mode=REQUIRED_PRIMARY_KEY,REPLICATE_MYISAM;
2626
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1
2727
SET GLOBAL wsrep_mode=1;
@@ -56,6 +56,10 @@ SET GLOBAL wsrep_mode=REPLICATE_ARIA;
5656
SELECT @@wsrep_mode;
5757
@@wsrep_mode
5858
REPLICATE_ARIA
59+
SET GLOBAL wsrep_mode=APPLIER_DISABLE_FK_WARNINGS;
60+
SELECT @@wsrep_mode;
61+
@@wsrep_mode
62+
APPLIER_DISABLE_FK_WARNINGS
5963
SET GLOBAL wsrep_mode=DISALLOW_LOCAL_GTID;
6064
SELECT @@wsrep_mode;
6165
@@wsrep_mode
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
--source include/galera_cluster.inc
2+
3+
#
4+
# Delete parent row that is needed for insert to child
5+
#
6+
CREATE TABLE parent (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
7+
CREATE TABLE child (f1 INTEGER PRIMARY KEY, p_id INTEGER,
8+
f2 INTEGER,
9+
CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES parent (f1) ON DELETE CASCADE) ;
10+
CREATE TABLE grandchild (f1 INTEGER PRIMARY KEY, p_id INTEGER,
11+
f2 INTEGER,
12+
CONSTRAINT fk_2 FOREIGN KEY (p_id) REFERENCES child (p_id)) ;
13+
14+
INSERT INTO parent VALUES (1, 1),(2,2);
15+
INSERT INTO child VALUES (1, 1, 1);
16+
17+
--connection node_1
18+
--echo # Make node 1 tolerate split-brain
19+
SET GLOBAL wsrep_provider_options = 'pc.ignore_sb=true';
20+
SET GLOBAL wsrep_provider_options = 'pc.weight=2';
21+
22+
--connection node_2
23+
--let $wait_condition = SELECT COUNT(*) = 1 FROM child;
24+
--source include/wait_condition.inc
25+
26+
SET SESSION wsrep_on=OFF;
27+
DELETE FROM child WHERE f1 = 1;
28+
29+
--connection node_1
30+
--echo # Fails in node_2 with Foreign key warning in table: `test`.`grandchild` constraint `fk_2` failed err: adding an index entry to a child table failed.
31+
INSERT INTO grandchild VALUES (1,1,1);
32+
33+
--echo # Restart node_2, force SST. This is needed as node_2 is on inconsistent state
34+
--connection node_2
35+
--source include/shutdown_mysqld.inc
36+
--remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat
37+
38+
--connection node_1
39+
--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'
40+
--source include/wait_condition.inc
41+
42+
--connection node_2
43+
--echo Starting server ...
44+
let $restart_noprint=2;
45+
--source include/start_mysqld.inc
46+
47+
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
48+
--source include/wait_condition.inc
49+
50+
--let $assert_count = 1
51+
--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.2.err
52+
--let $assert_text = Foreign key warning in table: \`test\`\.\`grandchild\` constraint \`fk_2\` failed err: adding an index entry to a child table failed.
53+
--let $assert_select = Foreign key warning in table: \`test\`\.\`grandchild\` constraint \`fk_2\` failed err: adding an index entry to a child table failed.
54+
--source include/assert_grep.inc
55+
56+
--connection node_1
57+
drop table grandchild;
58+
drop table child;
59+
drop table parent;
60+
# restore provider options
61+
SET GLOBAL wsrep_provider_options = 'pc.ignore_sb=false';
62+
SET GLOBAL wsrep_provider_options = 'pc.weight=1';
63+
64+
--connection node_2
65+
call mtr.add_suppression("WSREP: Foreign key warning in table");
66+
# These are required because test intentionally causes inconsistency
67+
call mtr.add_suppression("WSREP: Event 3 Write_rows_v1 apply failed");
68+
call mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on");
69+
call mtr.add_suppression("WSREP: Failed to apply write set");

mysql-test/suite/galera/t/MW-369.test

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#
2323

2424
--source include/galera_cluster.inc
25-
--source include/have_innodb.inc
25+
--source include/have_debug.inc
2626
--source include/have_debug_sync.inc
2727

2828
CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
@@ -340,3 +340,35 @@ SELECT * FROM cg;
340340

341341
DROP TABLE cg;
342342
DROP TABLE pg;
343+
344+
--connection node_1
345+
CREATE TABLE `pg-` (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB;
346+
CREATE TABLE `cg-` (f1 INTEGER PRIMARY KEY, p_id INTEGER,
347+
f2 INTEGER,
348+
CONSTRAINT `fk_1-$$` FOREIGN KEY (p_id) REFERENCES `pg-` (f1)) ;
349+
350+
INSERT INTO `pg-` VALUES (1, 0);
351+
INSERT INTO `pg-` VALUES (2, 0);
352+
353+
--let mw_369_parent_query = UPDATE `pg-` SET f2 = 1 WHERE f1 = 1
354+
--let $mw_369_child_query = INSERT INTO `cg-` VALUES (1, 1, 0)
355+
--source MW-369.inc
356+
357+
# Commit succeeds
358+
--connection node_1
359+
--reap
360+
call mtr.add_suppression("WSREP: Foreign key warning");
361+
362+
--echo # Now there should Foreign key constraint warning
363+
--let $assert_count = 1
364+
--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err
365+
--let $assert_text = Foreign key warning in table: \`test\`\.\`cg\` constraint \`fk_1\` failed err: Setting shared record lock to matching record in the child table failed \(Lock wait\).
366+
--let $assert_select = Foreign key warning in table: \`test\`\.\`cg\` constraint \`fk_1\` failed err: Setting shared record lock to matching record in the child table failed \(Lock wait\).
367+
--source include/assert_grep.inc
368+
369+
--connection node_2
370+
SELECT * FROM `pg-`;
371+
SELECT * FROM `cg-`;
372+
373+
DROP TABLE `cg-`;
374+
DROP TABLE `pg-`;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[no_warnings]
2+
wsrep-mode=APPLIER_DISABLE_FK_WARNINGS
3+
4+
[warnings]
5+
wsrep-mode=0

mysql-test/suite/galera/t/galera_FK_duplicate_client_insert.test

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,17 @@ while($counter > 0)
159159
--connection node_1
160160

161161
drop table user_session,user;
162+
163+
let $wsrep_mode = `SELECT @@GLOBAL.wsrep_mode`;
164+
165+
if ($wsrep_mode != APPLIER_DISABLE_FK_WARNINGS)
166+
{
167+
--echo # Now there should be 10 WSREP Foreign key constraint warnings
168+
--let $assert_count = 10
169+
--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err
170+
--let $assert_text = Foreign key warning in table: \`test\`\.\`user_session\` constraint \`user_session_ibfk_1\` failed err: Setting shared record lock to matching record in the child table failed \(Lock wait\).
171+
--let $assert_select = Foreign key warning in table: \`test\`\.\`user_session\` constraint \`user_session_ibfk_1\` failed err: Setting shared record lock to matching record in the child table failed \(Lock wait\).
172+
--source include/assert_grep.inc
173+
}
174+
175+
call mtr.add_suppression("WSREP: Foreign key warning in table");

0 commit comments

Comments
 (0)