Skip to content

Commit 8af5ab4

Browse files
committed
Merge MDEV-8354 into 10.0
2 parents a6087e7 + b89de2b commit 8af5ab4

File tree

4 files changed

+263
-7
lines changed

4 files changed

+263
-7
lines changed

mysql-test/suite/multi_source/gtid_ignore_duplicates.cnf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,25 @@
33
[mysqld.1]
44
log-slave-updates
55
loose-innodb
6+
binlog-format=mixed
67

78
[mysqld.2]
89
log-slave-updates
910
loose-innodb
11+
binlog-format=mixed
1012

1113
[mysqld.3]
1214
log-bin=server3-bin
1315
log-slave-updates
1416
loose-innodb
17+
binlog-format=mixed
1518

1619
[mysqld.4]
1720
server-id=4
1821
log-bin=server4-bin
1922
log-slave-updates
2023
loose-innodb
24+
binlog-format=mixed
2125

2226
[ENV]
2327
SERVER_MYPORT_4= @mysqld.4.port

mysql-test/suite/multi_source/gtid_ignore_duplicates.result

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,145 @@ a
242242
24
243243
25
244244
26
245+
*** MDEV-8354: out-of-order error with --gtid-ignore-duplicates and row-based replication ***
246+
SET default_master_connection = "b2a";
247+
STOP SLAVE;
248+
include/wait_for_slave_to_stop.inc
249+
SET default_master_connection = "c2a";
250+
STOP SLAVE;
251+
include/wait_for_slave_to_stop.inc
252+
SET default_master_connection = "c2b";
253+
STOP SLAVE;
254+
include/wait_for_slave_to_stop.inc
255+
SET default_master_connection = "b2c";
256+
STOP SLAVE;
257+
include/wait_for_slave_to_stop.inc
258+
SET @old_slave_mode=@@GLOBAL.slave_exec_mode;
259+
SET GLOBAL slave_exec_mode=IDEMPOTENT;
260+
SET @old_strict=@@GLOBAL.gtid_strict_mode;
261+
SET GLOBAL gtid_strict_mode=1;
262+
SET @old_dbug=@@GLOBAL.debug_dbug;
263+
SET GLOBAL debug_dbug="+d,inject_sleep_gtid_100_x_x";
264+
SET @old_domain=@@SESSION.gtid_domain_id;
265+
SET @old_format=@@SESSION.binlog_format;
266+
SET SESSION gtid_domain_id=100;
267+
SET SESSION binlog_format='row';
268+
INSERT INTO t1 VALUES (30);
269+
INSERT INTO t1 VALUES (31);
270+
INSERT INTO t1 VALUES (32);
271+
INSERT INTO t1 VALUES (33);
272+
INSERT INTO t1 VALUES (34);
273+
INSERT INTO t1 VALUES (35);
274+
INSERT INTO t1 VALUES (36);
275+
INSERT INTO t1 VALUES (37);
276+
INSERT INTO t1 VALUES (38);
277+
INSERT INTO t1 VALUES (39);
278+
INSERT INTO t1 VALUES (40);
279+
INSERT INTO t1 VALUES (41);
280+
INSERT INTO t1 VALUES (42);
281+
INSERT INTO t1 VALUES (43);
282+
INSERT INTO t1 VALUES (44);
283+
INSERT INTO t1 VALUES (45);
284+
INSERT INTO t1 VALUES (46);
285+
INSERT INTO t1 VALUES (47);
286+
INSERT INTO t1 VALUES (48);
287+
INSERT INTO t1 VALUES (49);
288+
SET SESSION gtid_domain_id=@old_domain;
289+
SET SESSION binlog_format=@old_format;
290+
include/save_master_gtid.inc
291+
include/sync_with_master_gtid.inc
292+
INSERT INTO t1 VALUES (50);
293+
include/save_master_gtid.inc
294+
SET default_master_connection = "b2c";
295+
START SLAVE;
296+
include/wait_for_slave_to_start.inc
297+
SELECT MASTER_GTID_WAIT("GTID", 30);
298+
MASTER_GTID_WAIT("GTID", 30)
299+
0
300+
SET default_master_connection = "b2a";
301+
START SLAVE;
302+
include/wait_for_slave_to_start.inc
303+
SET default_master_connection = "c2a";
304+
START SLAVE;
305+
include/wait_for_slave_to_start.inc
306+
include/sync_with_master_gtid.inc
307+
SELECT * FROM t1 WHERE a >= 30 ORDER BY a;
308+
a
309+
30
310+
31
311+
32
312+
33
313+
34
314+
35
315+
36
316+
37
317+
38
318+
39
319+
40
320+
41
321+
42
322+
43
323+
44
324+
45
325+
46
326+
47
327+
48
328+
49
329+
50
330+
SET default_master_connection = "c2b";
331+
START SLAVE;
332+
include/wait_for_slave_to_start.inc
333+
include/sync_with_master_gtid.inc
334+
SELECT * FROM t1 WHERE a >= 30 ORDER BY a;
335+
a
336+
30
337+
31
338+
32
339+
33
340+
34
341+
35
342+
36
343+
37
344+
38
345+
39
346+
40
347+
41
348+
42
349+
43
350+
44
351+
45
352+
46
353+
47
354+
48
355+
49
356+
50
357+
include/sync_with_master_gtid.inc
358+
SET GLOBAL debug_dbug=@old_dbug;
359+
SELECT * FROM t1 WHERE a >= 30 ORDER BY a;
360+
a
361+
30
362+
31
363+
32
364+
33
365+
34
366+
35
367+
36
368+
37
369+
38
370+
39
371+
40
372+
41
373+
42
374+
43
375+
44
376+
45
377+
46
378+
47
379+
48
380+
49
381+
50
382+
SET GLOBAL slave_exec_mode=@old_slave_mode;
383+
SET GLOBAL gtid_strict_mode=@old_strict;
245384
SET GLOBAL gtid_domain_id=0;
246385
STOP ALL SLAVES;
247386
Warnings:

mysql-test/suite/multi_source/gtid_ignore_duplicates.test

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
--source include/not_embedded.inc
22
--source include/have_innodb.inc
3+
--source include/have_debug.inc
4+
35

46
--echo *** Test all-to-all replication with --gtid-ignore-duplicates ***
57

@@ -258,6 +260,112 @@ SELECT * FROM t1 WHERE a >= 20 ORDER BY a;
258260
SELECT * FROM t1 WHERE a >= 20 ORDER BY a;
259261

260262

263+
--echo *** MDEV-8354: out-of-order error with --gtid-ignore-duplicates and row-based replication ***
264+
265+
# Have only A->C A->B initially.
266+
--connection server_1
267+
SET default_master_connection = "b2a";
268+
STOP SLAVE;
269+
--source include/wait_for_slave_to_stop.inc
270+
SET default_master_connection = "c2a";
271+
STOP SLAVE;
272+
--source include/wait_for_slave_to_stop.inc
273+
274+
--connection server_2
275+
SET default_master_connection = "c2b";
276+
STOP SLAVE;
277+
--source include/wait_for_slave_to_stop.inc
278+
279+
--connection server_3
280+
SET default_master_connection = "b2c";
281+
STOP SLAVE;
282+
--source include/wait_for_slave_to_stop.inc
283+
SET @old_slave_mode=@@GLOBAL.slave_exec_mode;
284+
SET GLOBAL slave_exec_mode=IDEMPOTENT;
285+
SET @old_strict=@@GLOBAL.gtid_strict_mode;
286+
SET GLOBAL gtid_strict_mode=1;
287+
288+
SET @old_dbug=@@GLOBAL.debug_dbug;
289+
# This will inject a small sleep that helps trigger the race. I did not manage
290+
# to create a non-sleeping version with debug_sync for this; the problem is
291+
# that once the bug is fixed, the race becomes impossible, so even with
292+
# debug_sync at best we can check that the debug_sync times out. Which is
293+
# just another way of adding a sleep.
294+
#
295+
# The bug was a race at this point where another multi-source connection
296+
# could incorrectly re-apply the same GTID, in case of row-based replication.
297+
SET GLOBAL debug_dbug="+d,inject_sleep_gtid_100_x_x";
298+
299+
--connection server_1
300+
SET @old_domain=@@SESSION.gtid_domain_id;
301+
SET @old_format=@@SESSION.binlog_format;
302+
SET SESSION gtid_domain_id=100;
303+
SET SESSION binlog_format='row';
304+
INSERT INTO t1 VALUES (30);
305+
INSERT INTO t1 VALUES (31);
306+
INSERT INTO t1 VALUES (32);
307+
INSERT INTO t1 VALUES (33);
308+
INSERT INTO t1 VALUES (34);
309+
INSERT INTO t1 VALUES (35);
310+
INSERT INTO t1 VALUES (36);
311+
INSERT INTO t1 VALUES (37);
312+
INSERT INTO t1 VALUES (38);
313+
INSERT INTO t1 VALUES (39);
314+
INSERT INTO t1 VALUES (40);
315+
INSERT INTO t1 VALUES (41);
316+
INSERT INTO t1 VALUES (42);
317+
INSERT INTO t1 VALUES (43);
318+
INSERT INTO t1 VALUES (44);
319+
INSERT INTO t1 VALUES (45);
320+
INSERT INTO t1 VALUES (46);
321+
INSERT INTO t1 VALUES (47);
322+
INSERT INTO t1 VALUES (48);
323+
INSERT INTO t1 VALUES (49);
324+
SET SESSION gtid_domain_id=@old_domain;
325+
SET SESSION binlog_format=@old_format;
326+
--source include/save_master_gtid.inc
327+
328+
--connection server_2
329+
--source include/sync_with_master_gtid.inc
330+
INSERT INTO t1 VALUES (50);
331+
--let $gtid=`SELECT @@last_gtid`
332+
--source include/save_master_gtid.inc
333+
334+
--connection server_3
335+
SET default_master_connection = "b2c";
336+
START SLAVE;
337+
--source include/wait_for_slave_to_start.inc
338+
--replace_result $gtid GTID
339+
eval SELECT MASTER_GTID_WAIT("$gtid", 30);
340+
# The bug occured here, the slave would get an out-of-order binlog error
341+
# due to trying to re-apply the 100-x-x transaction.
342+
343+
# Restart stopped multi-source connections, and sync up.
344+
--connection server_1
345+
SET default_master_connection = "b2a";
346+
START SLAVE;
347+
--source include/wait_for_slave_to_start.inc
348+
SET default_master_connection = "c2a";
349+
START SLAVE;
350+
--source include/wait_for_slave_to_start.inc
351+
--source include/sync_with_master_gtid.inc
352+
SELECT * FROM t1 WHERE a >= 30 ORDER BY a;
353+
354+
--connection server_2
355+
SET default_master_connection = "c2b";
356+
START SLAVE;
357+
--source include/wait_for_slave_to_start.inc
358+
--source include/sync_with_master_gtid.inc
359+
SELECT * FROM t1 WHERE a >= 30 ORDER BY a;
360+
361+
--connection server_3
362+
--source include/sync_with_master_gtid.inc
363+
SET GLOBAL debug_dbug=@old_dbug;
364+
SELECT * FROM t1 WHERE a >= 30 ORDER BY a;
365+
SET GLOBAL slave_exec_mode=@old_slave_mode;
366+
SET GLOBAL gtid_strict_mode=@old_strict;
367+
368+
261369
# Clean up.
262370
--connection server_1
263371
SET GLOBAL gtid_domain_id=0;

sql/rpl_rli.cc

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,6 +1768,13 @@ void rpl_group_info::cleanup_context(THD *thd, bool error)
17681768
rli->clear_flag(Relay_log_info::IN_STMT);
17691769
rli->clear_flag(Relay_log_info::IN_TRANSACTION);
17701770
}
1771+
1772+
/*
1773+
Ensure we always release the domain for others to process, when using
1774+
--gtid-ignore-duplicates.
1775+
*/
1776+
if (gtid_ignore_duplicate_state != GTID_DUPLICATE_NULL)
1777+
rpl_global_gtid_slave_state.release_domain_owner(this);
17711778
}
17721779

17731780
/*
@@ -1776,13 +1783,6 @@ void rpl_group_info::cleanup_context(THD *thd, bool error)
17761783
thd->variables.option_bits&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
17771784
thd->variables.option_bits&= ~OPTION_RELAXED_UNIQUE_CHECKS;
17781785

1779-
/*
1780-
Ensure we always release the domain for others to process, when using
1781-
--gtid-ignore-duplicates.
1782-
*/
1783-
if (gtid_ignore_duplicate_state != GTID_DUPLICATE_NULL)
1784-
rpl_global_gtid_slave_state.release_domain_owner(this);
1785-
17861786
/*
17871787
Reset state related to long_find_row notes in the error log:
17881788
- timestamp
@@ -1791,6 +1791,11 @@ void rpl_group_info::cleanup_context(THD *thd, bool error)
17911791
reset_row_stmt_start_timestamp();
17921792
unset_long_find_row_note_printed();
17931793

1794+
DBUG_EXECUTE_IF("inject_sleep_gtid_100_x_x", {
1795+
if (current_gtid.domain_id == 100)
1796+
my_sleep(50000);
1797+
};);
1798+
17941799
DBUG_VOID_RETURN;
17951800
}
17961801

0 commit comments

Comments
 (0)