-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MDEV-7611 mysqldump --dump-slave always starts stopped slave #3780
base: 10.5
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -184,7 +184,8 @@ static DYNAMIC_STRING dynamic_where; | |||||||||||||
static MYSQL_RES *get_table_name_result= NULL; | ||||||||||||||
static MEM_ROOT glob_root; | ||||||||||||||
static MYSQL_RES *routine_res, *routine_list_res; | ||||||||||||||
|
||||||||||||||
static size_t n_stopped_replicas= 0; | ||||||||||||||
static char (*stopped_replicas)[NAME_CHAR_LEN]= NULL; | ||||||||||||||
|
||||||||||||||
#include <sslopt-vars.h> | ||||||||||||||
FILE *md_result_file= 0; | ||||||||||||||
|
@@ -1854,6 +1855,7 @@ static void free_resources() | |||||||||||||
mysql_close(mysql); | ||||||||||||||
mysql= 0; | ||||||||||||||
} | ||||||||||||||
my_free(stopped_replicas); | ||||||||||||||
my_free(order_by); | ||||||||||||||
my_free(opt_password); | ||||||||||||||
my_free(current_host); | ||||||||||||||
|
@@ -6097,12 +6099,22 @@ static int do_stop_slave_sql(MYSQL *mysql_con) | |||||||||||||
{ | ||||||||||||||
MYSQL_RES *slave; | ||||||||||||||
MYSQL_ROW row; | ||||||||||||||
// do_stop_slave_sql() should only be called once | ||||||||||||||
DBUG_ASSERT(!stopped_replicas); | ||||||||||||||
|
||||||||||||||
if (mysql_query_with_error_report(mysql_con, &slave, | ||||||||||||||
multi_source ? | ||||||||||||||
"SHOW ALL SLAVES STATUS" : | ||||||||||||||
"SHOW SLAVE STATUS")) | ||||||||||||||
return(1); | ||||||||||||||
stopped_replicas= my_malloc(PSI_NOT_INSTRUMENTED, | ||||||||||||||
slave->row_count*NAME_CHAR_LEN + 1, MYF(MY_WME)); | ||||||||||||||
if (!stopped_replicas) | ||||||||||||||
{ | ||||||||||||||
mysql_free_result(slave); | ||||||||||||||
fputs("Error: Not enough memory to store current replica status\n", stderr); | ||||||||||||||
return 1; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
/* Loop over all slaves */ | ||||||||||||||
while ((row= mysql_fetch_row(slave))) | ||||||||||||||
|
@@ -6123,6 +6135,8 @@ static int do_stop_slave_sql(MYSQL *mysql_con) | |||||||||||||
mysql_free_result(slave); | ||||||||||||||
return 1; | ||||||||||||||
} | ||||||||||||||
strmov(stopped_replicas[n_stopped_replicas++], | ||||||||||||||
multi_source ? row[0] : ""); | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pedantically supporting no-multi-source on a best effort basis Lines 7010 to 7015 in 6aa47fa
|
||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
|
@@ -6250,43 +6264,29 @@ static int do_show_slave_status(MYSQL *mysql_con, int have_mariadb_gtid, | |||||||||||||
|
||||||||||||||
static int do_start_slave_sql(MYSQL *mysql_con) | ||||||||||||||
{ | ||||||||||||||
MYSQL_RES *slave; | ||||||||||||||
MYSQL_ROW row; | ||||||||||||||
int error= 0; | ||||||||||||||
DBUG_ENTER("do_start_slave_sql"); | ||||||||||||||
|
||||||||||||||
/* We need to check if the slave sql is stopped in the first place */ | ||||||||||||||
if (mysql_query_with_error_report(mysql_con, &slave, | ||||||||||||||
multi_source ? | ||||||||||||||
"SHOW ALL SLAVES STATUS" : | ||||||||||||||
"SHOW SLAVE STATUS")) | ||||||||||||||
DBUG_RETURN(1); | ||||||||||||||
|
||||||||||||||
while ((row= mysql_fetch_row(slave))) | ||||||||||||||
for (; n_stopped_replicas--;) | ||||||||||||||
Comment on lines
6265
to
+6269
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To use the new list instead of SHOW SLAVE STATUS, I essentially rewrote |
||||||||||||||
{ | ||||||||||||||
DBUG_PRINT("info", ("Connection: '%s' status: '%s'", | ||||||||||||||
multi_source ? row[0] : "", row[11 + multi_source])); | ||||||||||||||
if (row[11 + multi_source]) | ||||||||||||||
/* | ||||||||||||||
do_start_slave_sql() should only be called | ||||||||||||||
sometime after do_stop_slave_sql() suceeds | ||||||||||||||
*/ | ||||||||||||||
char* stopped_replica= stopped_replicas[n_stopped_replicas]; | ||||||||||||||
char query[sizeof("START SLAVE ''") + NAME_CHAR_LEN]; | ||||||||||||||
DBUG_PRINT("info", ("Connection: '%.*s'", NAME_CHAR_LEN, stopped_replica)); | ||||||||||||||
// if SLAVE SQL is running, start it anyway to warn unexpected state change | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The program runs SHOW SLAVE STATUS multiple times thoughout the various step functions:
Perhaps the intent is in case replication configs change in the middle of |
||||||||||||||
if (multi_source) | ||||||||||||||
sprintf(query, "START SLAVE '%.*s'", NAME_CHAR_LEN, stopped_replica); | ||||||||||||||
|
||||||||||||||
if (mysql_query_with_error_report(mysql_con, 0, | ||||||||||||||
multi_source ? query : "START SLAVE")) | ||||||||||||||
{ | ||||||||||||||
/* if SLAVE SQL is not running, we don't start it */ | ||||||||||||||
if (strcmp(row[11 + multi_source], "Yes")) | ||||||||||||||
{ | ||||||||||||||
char query[160]; | ||||||||||||||
if (multi_source) | ||||||||||||||
sprintf(query, "START SLAVE '%.80s'", row[0]); | ||||||||||||||
else | ||||||||||||||
strmov(query, "START SLAVE"); | ||||||||||||||
|
||||||||||||||
if (mysql_query_with_error_report(mysql_con, 0, query)) | ||||||||||||||
{ | ||||||||||||||
fprintf(stderr, "%s: Error: Unable to start slave '%s'\n", | ||||||||||||||
my_progname_short, multi_source ? row[0] : ""); | ||||||||||||||
error= 1; | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
fprintf(stderr, "%s: Error: Unable to start slave '%.*s'\n", | ||||||||||||||
my_progname_short, NAME_CHAR_LEN, stopped_replica); | ||||||||||||||
error= 1; | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
mysql_free_result(slave); | ||||||||||||||
DBUG_RETURN(error); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
connect replica,127.0.0.1,root,,,$SERVER_MYPORT_1; | ||
connect active_primary,127.0.0.1,root,,,$SERVER_MYPORT_2; | ||
connect inactive_primary,127.0.0.1,root,,,$SERVER_MYPORT_3; | ||
connection replica; | ||
CHANGE MASTER 'active_repl' TO master_port=MYPORT_2, master_host='127.0.0.1', master_user='root'; | ||
START REPLICA 'active_repl'; | ||
CHANGE MASTER 'inactive_repl' TO master_port=MYPORT_3, master_host='127.0.0.1', master_user='root'; | ||
STOP REPLICA 'inactive_repl'; | ||
Warnings: | ||
Note 1255 Slave already has been stopped | ||
# Basic | ||
MYSQL_DUMP --compact --dump-slave --include-master-host-port test | ||
/*M!999999\- enable the sandbox mode */ | ||
CHANGE MASTER 'active_repl' TO MASTER_HOST='127.0.0.1', MASTER_PORT=MYPORT_2, MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START; | ||
CHANGE MASTER 'inactive_repl' TO MASTER_HOST='127.0.0.1', MASTER_PORT=MYPORT_3, MASTER_LOG_FILE='', MASTER_LOG_POS=BINLOG_START; | ||
|
||
-- SET GLOBAL gtid_slave_pos=''; | ||
# MDEV-7611 mysqldump --dump-slave always starts stopped slave | ||
MYSQL_DUMP --compact --dump-slave test | ||
/*M!999999\- enable the sandbox mode */ | ||
CHANGE MASTER 'active_repl' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START; | ||
CHANGE MASTER 'inactive_repl' TO MASTER_LOG_FILE='', MASTER_LOG_POS=BINLOG_START; | ||
|
||
-- SET GLOBAL gtid_slave_pos=''; | ||
START REPLICA 'active_repl'; | ||
Warnings: | ||
Note 1254 Slave is already running | ||
STOP REPLICA 'inactive_repl'; | ||
Warnings: | ||
Note 1255 Slave already has been stopped | ||
# MDEV-5624 mysqldump --dump-slave option does not restart the replication if the dump has failed | ||
MYSQL_DUMP --compact --dump-slave no_such_db | ||
/*M!999999\- enable the sandbox mode */ | ||
CHANGE MASTER 'active_repl' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START; | ||
CHANGE MASTER 'inactive_repl' TO MASTER_LOG_FILE='', MASTER_LOG_POS=BINLOG_START; | ||
|
||
START REPLICA 'active_repl'; | ||
Warnings: | ||
Note 1254 Slave is already running | ||
STOP REPLICA 'inactive_repl'; | ||
Warnings: | ||
Note 1255 Slave already has been stopped | ||
# Cleanup | ||
include/reset_master_slave.inc | ||
disconnect replica; | ||
disconnect active_primary; | ||
disconnect inactive_primary; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Interactions with --dump-slave; based on `main.rpl_mysqldump_slave` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and |
||
|
||
--source include/have_log_bin.inc | ||
|
||
--connect (replica,127.0.0.1,root,,,$SERVER_MYPORT_1) | ||
--connect (active_primary,127.0.0.1,root,,,$SERVER_MYPORT_2) | ||
--connect (inactive_primary,127.0.0.1,root,,,$SERVER_MYPORT_3) | ||
--connection replica | ||
|
||
--replace_result $SERVER_MYPORT_2 MYPORT_2 | ||
--eval CHANGE MASTER 'active_repl' TO master_port=$SERVER_MYPORT_2, master_host='127.0.0.1', master_user='root' | ||
START REPLICA 'active_repl'; | ||
--replace_result $SERVER_MYPORT_3 MYPORT_3 | ||
--eval CHANGE MASTER 'inactive_repl' TO master_port=$SERVER_MYPORT_3, master_host='127.0.0.1', master_user='root' | ||
STOP REPLICA 'inactive_repl'; | ||
|
||
--echo # Basic | ||
--echo MYSQL_DUMP --compact --dump-slave --include-master-host-port test | ||
--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/ | ||
--replace_result $SERVER_MYPORT_2 MYPORT_2 $SERVER_MYPORT_3 MYPORT_3 | ||
--exec $MYSQL_DUMP --compact --dump-slave --include-master-host-port test | ||
|
||
--echo # MDEV-7611 mysqldump --dump-slave always starts stopped slave | ||
--echo MYSQL_DUMP --compact --dump-slave test | ||
--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/ | ||
--exec $MYSQL_DUMP --compact --dump-slave test | ||
START REPLICA 'active_repl'; | ||
STOP REPLICA 'inactive_repl'; | ||
|
||
--echo # MDEV-5624 mysqldump --dump-slave option does not restart the replication if the dump has failed | ||
--echo MYSQL_DUMP --compact --dump-slave no_such_db | ||
--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/ | ||
--error 2 | ||
--exec $MYSQL_DUMP --compact --dump-slave no_such_db | ||
START REPLICA 'active_repl'; | ||
STOP REPLICA 'inactive_repl'; | ||
|
||
--echo # Cleanup | ||
--source include/reset_master_slave.inc | ||
--disconnect replica | ||
--disconnect active_primary | ||
--disconnect inactive_primary |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -71,7 +71,6 @@ select @@global.gtid_slave_pos as "after initial slave got in sync"; | |
--echo # 3. A | ||
# Two dumps prepared to be restored in the following loop | ||
--exec $MYSQL_DUMP_SLAVE --dump-slave --gtid mysql gtid_slave_pos > $MYSQLTEST_VARDIR/tmp/dump_2.sql | ||
--source include/stop_slave.inc | ||
Comment on lines
73
to
-74
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test was aware 😄. |
||
|
||
--exec $MYSQL_DUMP_SLAVE --master-data --gtid mysql gtid_slave_pos > $MYSQLTEST_VARDIR/tmp/dump_1.sql | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel that it’s wrong wasting memory on short names and already-stopped replicas, but I feel that it’s more wrong spending extra effort
realloc
ing unpredictably.I’d like to iterate the
MYSQL_RES
an additional time before the following loop to sum up name sizes of (only) active replications.Question: How to rewind it from
mysql_fetch_row()
s?Note I didn’t check size overflow here because of the Broken Windows Theory:
server/client/mysqldump.c
Line 1986 in 6aa47fa
server/client/mysqldump.c
Line 6620 in 6aa47fa