Skip to content

Commit ad5bbb3

Browse files
author
Sven Sandberg
committed
BUG#18385953 - RPL_GTID_STRESS_FAILOVER FAILS WITH "ERROR IN SYNC_WITH_MASTER.INC"
This test failed sporadically in the cleanup code. The cleanup code contained this: for each server: DROP DATABASE --source include/stop_slave.inc CHANGE MASTER TO MASTER_AUTO_POSITION = 0; --source include/start_slave.inc The problem is that CHANGE MASTER will drop the relay logs. If the IO thread was ahead of the SQL thread at this point, received and not-yet-executed transactions in the relay log would be lost. Since it does not use the auto-position protocol when it does the start_slave.inc, replication would resume after the lost transaction rather than retransmit it. This caused two types of failures: 1. The IO thread could be stopped in the middle of a transaction, when the SQL thread had processed only up to the last complete transaction. Here all transactions consist of two events: Gtid followed by Query. Thus, the last received transaction was a Gtid and after start_slave.inc the slave would receive a Query. The slave SQL thread would then see a Query without Gtid. This looks like an anonymous transaction, which is not allowed when GTID_MODE = ON. So the SQL thread would stop with error 1782: "Error '@@SESSION.GTID_NEXT cannot be set to ANONYMOUS when @@GLOBAL.GTID_MODE = ON.' on query. Default database: 'db_3'. Query: 'DROP DATABASE db_3'". 2. The IO thread could be stopped between transactions, when the SQL thread had processed only up to the second-last transaction. Then the entire transaction would get lost. Later, in rpl_sync.inc, the GTID would not be received at all by the slave, so the sync would fail with a timeout. Fixed by dropping the databases and syncing all servers before stopping all the slave threads and executing CHANGE MASTER.
1 parent 1a5d481 commit ad5bbb3

File tree

7 files changed

+190
-11
lines changed

7 files changed

+190
-11
lines changed

mysql-test/include/begin_include_file.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#
3535
# # At the beginning of include/my_file.inc:
3636
# --let $include_filename= my_file.inc
37+
# [--let $include_silent= 1]
3738
# [--let $rpl_debug= 1]
3839
# --source include/begin_include_file.inc
3940
#

mysql-test/include/save_io_thread_pos.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
if ($use_gtids)
3030
{
31-
--let $_saved_gtids= query_get_value(SHOW SLAVE STATUS, Retrieved_Gtid_set, 1)
31+
--let $_saved_gtids= query_get_value(SHOW SLAVE STATUS, Retrieved_Gtid_Set, 1)
3232
if ($rpl_debug)
3333
{
3434
--echo save_io_thread_pos.inc saved gtid='$_saved_gtids'
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# ==== Purpose ====
2+
#
3+
# Print the contents of all binary logs to the result log. This must
4+
# only be used for debugging.
5+
#
6+
# ==== Usage ====
7+
#
8+
# [--let $output_file= FILENAME]
9+
# [--let $append= 1]
10+
# [--let $rpl_debug= 1]
11+
# --source include/show_all_binlogs.inc
12+
#
13+
# Parameters:
14+
#
15+
# $output_file
16+
# By default, output is printed to the result log. If you need to
17+
# print it to a specific file, specify the filename with this
18+
# parameter.
19+
#
20+
# $append
21+
# By default, if $output_file is specified and the file exists,
22+
# this script truncates the file before it writes to it. If
23+
# $append is specified, the file is not truncated and the contents
24+
# of the binary log is appended to the end.
25+
#
26+
# $rpl_debug
27+
# See rpl_init.inc
28+
29+
--let $include_filename= show_all_binlogs.inc
30+
--source include/begin_include_file.inc
31+
32+
33+
--disable_query_log
34+
35+
if ($output_file == '')
36+
{
37+
--echo DO_NOT_CHECK_IN_THIS_LINE: include/show_all_binlogs.inc should only be used for debugging. Never check in a test that calls it on success.
38+
}
39+
40+
--let $number= 1
41+
--let $binlog_file= query_get_value(SHOW BINARY LOGS, Log_name, $number)
42+
while ($binlog_file != 'No such row')
43+
{
44+
--let $statement= SHOW BINLOG EVENTS IN '$binlog_file'
45+
--let $header= ======== $statement ========
46+
47+
if ($output_file != '')
48+
{
49+
--let $write_var= $header
50+
--let $write_to_file= $output_file
51+
--source include/write_var_to_file.inc
52+
53+
--source include/write_result_to_file.inc
54+
}
55+
if ($output_file == '')
56+
{
57+
--echo $header
58+
eval $statement;
59+
}
60+
--inc $number
61+
62+
--let $binlog_file= query_get_value(SHOW BINARY LOGS, Log_name, $number)
63+
}
64+
65+
66+
--source include/end_include_file.inc
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# ==== Purpose ====
2+
#
3+
# Print the contents of all relay logs to the result log. This must
4+
# only be used for debugging.
5+
#
6+
# ==== Usage ====
7+
#
8+
# [--let $output_file= FILENAME]
9+
# [--let $append= 1]
10+
# [--let $rpl_debug= 1]
11+
# --source include/show_all_binlogs.inc
12+
#
13+
# Parameters:
14+
#
15+
# $output_file
16+
# By default, output is printed to the result log. If you need to
17+
# print it to a specific file, specify the filename with this
18+
# parameter.
19+
#
20+
# $append
21+
# By default, if $output_file is specified and the file exists,
22+
# this script truncates the file before it writes to it. If
23+
# $append is specified, the file is not truncated and the contents
24+
# of the binary log is appended to the end.
25+
#
26+
# $rpl_debug
27+
# See rpl_init.inc
28+
29+
--let $include_filename= show_all_relay_logs.inc
30+
--source include/begin_include_file.inc
31+
32+
33+
--disable_query_log
34+
35+
if ($output_file == '')
36+
{
37+
--echo DO_NOT_CHECK_IN_THIS_LINE: include/show_all_relay_logs.inc should only be used for debugging. Never check in a test that calls it on success.
38+
}
39+
40+
--let $last_relay_log_file= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1)
41+
--let $relay_log_base= `SELECT SUBSTRING_INDEX('$last_relay_log_file', '.', 1)`
42+
--let $relay_log_count= `SELECT CONCAT('1', SUBSTRING_INDEX('$last_relay_log_file', '.', -1)) - 1000000`
43+
--let $number= 1
44+
while ($number <= $relay_log_count)
45+
{
46+
--let $padded_number= `SELECT LPAD('$number', 6, '0')`
47+
--let $statement= SHOW RELAYLOG EVENTS IN '$relay_log_base.$padded_number'
48+
--let $header= ======== $statement ========
49+
50+
if ($output_file != '')
51+
{
52+
--let $write_to_file= $output_file
53+
--let $write_var= $header
54+
--let $allow_error= 1
55+
--source include/write_var_to_file.inc
56+
57+
--source include/write_result_to_file.inc
58+
}
59+
if ($output_file == '')
60+
{
61+
--echo $header
62+
--error 0, 1220 # 1220 = ER_ERROR_WHEN_EXECUTING_COMMAND
63+
eval $statement;
64+
}
65+
66+
--inc $number
67+
}
68+
69+
70+
--source include/end_include_file.inc

mysql-test/include/write_result_to_file.inc

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
# --let $statement= <STATEMENT>
1313
# --let $output_file= {<FILE>|GENERATE}
1414
# [--let $dont_print_statement= 1]
15+
# [--let $allow_error= 1]
16+
# [--let $append= 1]
1517
# --source include/write_result_to_file.inc
1618
#
1719
# Parameters:
@@ -27,6 +29,14 @@
2729
# By default, the statement is echoed to the result log. If the
2830
# statement contains non-deterministic output, set this variable
2931
# to suppress it.
32+
#
33+
# $allow_error
34+
# By default, this script causes the test to fail if the statement
35+
# generates an error. If $allow_error is set, errors are ignored.
36+
#
37+
# $append
38+
# By default, any existing file is overwritten. If $append is
39+
# specified, and the file exists, it appends to the file.
3040

3141
# Get the port and socket used by mysqld on current connection
3242
--let _WRTF_SERVER_PORT= `SELECT @@PORT`
@@ -58,19 +68,37 @@ if ($output_file == GENERATE)
5868
}
5969
--let _WRTF_OUTPUT_FILE= $output_file
6070

71+
if ($allow_error)
72+
{
73+
--let _WRTF_ALLOW_ERROR= 1
74+
}
75+
if (!$allow_error)
76+
{
77+
--let _WRTF_ALLOW_ERROR= 0
78+
}
79+
if ($append)
80+
{
81+
--let _WRTF_APPEND= 1
82+
}
83+
if (!$append)
84+
{
85+
--let _WRTF_APPEND= 0
86+
}
87+
6188
perl;
6289
use strict;
6390
my $stmt= $ENV{'_WRTF_STATEMENT'};
6491
# Connecting mysql to same mysqld as current connectiona
6592
# by overriding port and socket
66-
my $mysql = $ENV{'MYSQL'};
93+
my $mysql= $ENV{'MYSQL'};
6794
my $server_port= $ENV{'_WRTF_SERVER_PORT'};
6895
my $server_socket= $ENV{'_WRTF_SERVER_SOCKET'};
96+
my $redirection_type= $ENV{'_WRTF_APPEND'} ? '>>' : '>';
6997
$mysql .= " --port=$server_port --socket=$server_socket";
7098
my $outfile = $ENV{'_WRTF_OUTPUT_FILE'};
71-
open MYSQL, "| $mysql > $outfile" or die "Failed to open MYSQL pipe: '$mysql > $outfile'";
99+
open MYSQL, "| $mysql $redirection_type $outfile" or die "Failed to open MYSQL pipe: '$mysql > $outfile'";
72100
print MYSQL $stmt, ';' or die "Error printing statement to MYSQL pipe: $!";
73-
close MYSQL or die "Error closing MYSQL pipe: $!";
101+
close MYSQL or $ENV{'_WRTF_ALLOW_ERROR'} or die "Error closing MYSQL pipe: $!";
74102
EOF
75103

76104
--let $include_filename= write_result_to_file.inc [$write_result_msg]

mysql-test/suite/rpl/r/rpl_gtid_stress_failover.result

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ Check that GTID_EXECUTED is equal on all servers.
1515
Check that database state is equal on all servers.
1616
include/diff_servers.inc [servers=1 2 3 4 5 ]
1717
==== Clean up ====
18+
include/rpl_sync.inc
1819
include/rpl_end.inc

mysql-test/suite/rpl/t/rpl_gtid_stress_failover.test

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#Want to skip this test from daily Valgrind execution
2-
--source include/no_valgrind_without_big.inc
31
# ==== Purpose ====
42
#
53
# Test that it is possible to change the topology completely randomly,
@@ -79,8 +77,13 @@
7977
#
8078
# ==== References ====
8179
#
82-
# Created as part of WL#3584: Global Transaction Identifiers
80+
# WL#3584: Global Transaction Identifiers
81+
# - Created as part of this worklog
82+
# BUG#18385953: RPL_GTID_STRESS_FAILOVER FAILS WITH "ERROR IN SYNC_WITH_MASTER.INC"
83+
# - fixed bug in cleanup code
8384

85+
#Want to skip this test from daily Valgrind execution
86+
--source include/no_valgrind_without_big.inc
8487
--source include/big_test.inc
8588
--source include/have_gtid.inc
8689

@@ -97,7 +100,10 @@
97100

98101
--echo ==== Configure ====
99102

100-
--let $max_seconds= 300
103+
if ($max_seconds == '')
104+
{
105+
--let $max_seconds= 300
106+
}
101107
if ($max_iterations == '')
102108
{
103109
--let $max_iterations= 10000
@@ -394,7 +400,7 @@ while ($server <= $n_servers)
394400
{
395401
--source include/show_rpl_debug_info.inc
396402
--echo ERROR: GTID_EXECUTED differs between server 1 and server $server
397-
--echo ERROR: GTID_EXECUTED on server 1: '$saved_gtid_executed'
403+
--echo ERROR: GTID_EXECUTED on server 1: '$last_gtid_executed'
398404
--echo ERROR: GTID_EXECUTED on server $server: '$gtid_executed'
399405
--die GTID_EXECUTED differs between two servers
400406
}
@@ -410,15 +416,22 @@ while ($server <= $n_servers)
410416

411417
--echo ==== Clean up ====
412418

419+
# drop database
413420
--connection default
414421
--let $server= 1
415422
while ($server <= $n_servers)
416423
{
417-
--connection default
418424
eval DROP DATABASE db_$server;
425+
--inc $server
426+
}
427+
--source include/rpl_sync.inc
419428

420-
# restoring the AUTO_POSITION
429+
# restore AUTO_POSITION
430+
--let $server= 1
431+
while ($server <= $n_servers)
432+
{
421433
--connection server_$server
434+
422435
--let $include_silent=1
423436
--source include/stop_slave.inc
424437
CHANGE MASTER TO MASTER_AUTO_POSITION=0;

0 commit comments

Comments
 (0)