Skip to content

Commit 69bc29c

Browse files
committed
MDEV-39880 Reïmplement MDEV-37146 to include MDEV-39519
MDEV-39519 added MySQL 8 compatibility to `mariadb-dump --dump-slave` by attempting `SHOW REPLICA STATUS` first and then `SHOW SLAVE STATUS`. This conflicted with MDEV-37146, where `mariadb-dump --dump-slave` queries either `SELECT … FROM information_schema.SLAVE_STATUS` or `SHOW ALL SLAVES STATUS` depending on the server version. This commit merges MDEV-37146 and MDEV-39519: * Use MDEV-39519’s strategy based on syntax error handling. * Use MDEV-37146’s preference order: 1. `SELECT … FROM information_schema.SLAVE_STATUS` 2. `SHOW ALL SLAVES STATUS` 3. `SHOW REPLICA STATUS` (for MySQL compatibility _only_) * Send `STOP`/`START REPLICA SQL_THREAD FOR CHANNEL '…'` commands for both MariaDB (est. 10.7) and MySQL. * Refactor column indices to variables set when a query succeeds. * Partially revert MDEV-37146’s removal of `--dump-slave`’s support for pre-GTID & pre-multi-source, but tailored for MySQL compatibility; coverage for MariaDB pre-10.0 is not fully restored.
1 parent 84c246c commit 69bc29c

1 file changed

Lines changed: 68 additions & 37 deletions

File tree

client/mysqldump.cc

Lines changed: 68 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -176,17 +176,20 @@ static uint opt_use_gtid;
176176
static uint my_end_arg;
177177
static char * opt_mysql_unix_port=0;
178178
static int first_error=0;
179-
/**
180-
`true` for 11.6 or above servers, `false` otherwise.
181-
@deprecated This and its `false` branches are to be removed after 11.4's EOL.
182-
*/
183179
static bool have_info_schema_slave_status;
184180
static DYNAMIC_STRING extended_row;
185181
static DYNAMIC_STRING dynamic_where;
186182
static MYSQL_RES *get_table_name_result= NULL;
187183
static MEM_ROOT glob_root;
188184
static MYSQL_RES *routine_res, *routine_list_res, *slave_status_res= NULL;
189185

186+
static struct
187+
{
188+
ptrdiff_t connection_name, slave_sql_running,
189+
master_host, master_port,
190+
relay_master_log_file, exec_master_log_pos;
191+
} slave_status_indices;
192+
190193

191194
#include <sslopt-vars.h>
192195
FILE *md_result_file= 0;
@@ -6499,23 +6502,48 @@ static int do_stop_slave_sql(MYSQL *mysql_con)
64996502
// do_stop_slave_sql() should only be called once
65006503
DBUG_ASSERT(!slave_status_res);
65016504

6502-
if (mysql_query_with_error_report(mysql_con, &slave_status_res,
6503-
have_info_schema_slave_status ?
6505+
// 11.6 and above
6506+
switch (mysql_query_with_error_report(mysql_con, &slave_status_res,
65046507
"SELECT Connection_name FROM information_schema.SLAVE_STATUS"
65056508
// If the slave's SQL thread is not running, we don't stop (or start) it.
6506-
" WHERE Slave_SQL_Running <> 'No'" :
6507-
"SHOW ALL SLAVES STATUS"
6508-
))
6509-
return(1);
6509+
" WHERE Slave_SQL_Running <> 'No'", true
6510+
)) {
6511+
default:
6512+
return 1;
6513+
case 0:
6514+
have_info_schema_slave_status= true;
6515+
break;
6516+
case -1:
6517+
have_info_schema_slave_status= false;
6518+
// Between 10.0 and 11.5 inclusive
6519+
switch (mysql_query_with_error_report(mysql_con, &slave_status_res,
6520+
"SHOW ALL SLAVES STATUS", true
6521+
)) {
6522+
default:
6523+
return 1;
6524+
case 0:
6525+
slave_status_indices= {0, 13, 3, 5, 11, 23};
6526+
break;
6527+
case -1:
6528+
// MySQL 8.0.22 and above
6529+
if (mysql_query_with_error_report(mysql_con, &slave_status_res,
6530+
"SHOW REPLICA STATUS"
6531+
))
6532+
return 1;
6533+
slave_status_indices= {55, 11, 1, 3, 9, 21};
6534+
}
6535+
}
6536+
65106537
// Loop over all slaves
65116538
while ((row= mysql_fetch_row(slave_status_res)))
65126539
{
65136540
if ((have_info_schema_slave_status ||
6514-
strcmp(row[/* Slave_SQL_Running */ 13], "No")))
6541+
strcmp(row[slave_status_indices.slave_sql_running], "No")))
65156542
{
6516-
char query[25 + NAME_CHAR_LEN]; // sizeof(snprintf)
6517-
snprintf(query, sizeof(query), "STOP SLAVE '%.*s' SQL_THREAD",
6518-
NAME_CHAR_LEN, row[/* Connection_name */ 0]);
6543+
char query[37 + NAME_CHAR_LEN]; // sizeof(snprintf)
6544+
snprintf(query, sizeof(query),
6545+
"STOP SLAVE SQL_THREAD FOR CHANNEL '%.*s'",
6546+
NAME_CHAR_LEN, row[slave_status_indices.connection_name]);
65196547
if (mysql_query_with_error_report(mysql_con, nullptr, query))
65206548
return 1;
65216549
}
@@ -6541,7 +6569,7 @@ static int add_slave_statements(void)
65416569
return(0);
65426570
}
65436571

6544-
static int do_show_slave_status(MYSQL *mysql_con,
6572+
static int do_show_slave_status(MYSQL *mysql_con, int have_mariadb_gtid,
65456573
int use_gtid, char *set_gtid_pos,
65466574
size_t set_gtid_pos_size)
65476575
{
@@ -6551,7 +6579,6 @@ static int do_show_slave_status(MYSQL *mysql_con,
65516579
(opt_slave_data == MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL) ? "-- " : "";
65526580
const char *gtid_comment_prefix= (use_gtid ? comment_prefix : "-- ");
65536581
const char *nogtid_comment_prefix= (!use_gtid ? comment_prefix : "-- ");
6554-
char gtid_pos[MAX_GTID_LENGTH];
65556582

65566583
if (have_info_schema_slave_status)
65576584
{
@@ -6566,6 +6593,7 @@ static int do_show_slave_status(MYSQL *mysql_con,
65666593
mysql_free_result(slave);
65676594
return 1;
65686595
}
6596+
slave_status_indices= {0, /* unused */ 3, 1, 2, 3, 4};
65696597
}
65706598
else
65716599
{
@@ -6574,13 +6602,18 @@ static int do_show_slave_status(MYSQL *mysql_con,
65746602
slave= slave_status_res;
65756603
}
65766604

6577-
if (get_gtid_pos(gtid_pos, false))
6605+
if (have_mariadb_gtid)
65786606
{
6579-
mysql_free_result(slave);
6580-
return 1;
6607+
char gtid_pos[MAX_GTID_LENGTH];
6608+
if (get_gtid_pos(gtid_pos, false))
6609+
{
6610+
if (have_info_schema_slave_status)
6611+
mysql_free_result(slave);
6612+
return 1;
6613+
}
6614+
snprintf(set_gtid_pos, set_gtid_pos_size,
6615+
fmt_gtid_pos, gtid_comment_prefix, gtid_pos);
65816616
}
6582-
snprintf(set_gtid_pos, set_gtid_pos_size,
6583-
fmt_gtid_pos, gtid_comment_prefix, gtid_pos);
65846617

65856618
print_comment(md_result_file, 0,
65866619
"\n-- The following is the replication SQL position "
@@ -6603,16 +6636,18 @@ static int do_show_slave_status(MYSQL *mysql_con,
66036636
if (use_gtid)
66046637
fprintf(md_result_file,
66056638
"%sCHANGE MASTER '%.*s' TO MASTER_USE_GTID=slave_pos;\n",
6606-
gtid_comment_prefix, NAME_CHAR_LEN, row[/* Connection_name */ 0]);
6639+
gtid_comment_prefix,
6640+
NAME_CHAR_LEN, row[slave_status_indices.connection_name]);
66076641
fprintf(md_result_file, "%sCHANGE MASTER '%.*s' TO ",
6608-
nogtid_comment_prefix, NAME_CHAR_LEN, row[/* Connection_name */ 0]);
6642+
nogtid_comment_prefix,
6643+
NAME_CHAR_LEN, row[slave_status_indices.connection_name]);
66096644
if (opt_include_master_host_port)
66106645
fprintf(md_result_file, "MASTER_HOST='%s', MASTER_PORT=%s, ",
6611-
row[have_info_schema_slave_status ? 1 : /* Master_Host */ 3],
6612-
row[have_info_schema_slave_status ? 2 : /* Master_Port */ 5]);
6646+
row[slave_status_indices.master_host],
6647+
row[slave_status_indices.master_port]);
66136648
fprintf(md_result_file, "MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n",
6614-
row[have_info_schema_slave_status ? 3 : /* Relay_Master_Log_File */ 11],
6615-
row[have_info_schema_slave_status ? 4 : /* Exec_Master_Log_Pos */ 23]);
6649+
row[slave_status_indices.relay_master_log_file],
6650+
row[slave_status_indices.exec_master_log_pos ]);
66166651
check_io(md_result_file);
66176652
}
66186653

@@ -6641,12 +6676,12 @@ static int do_start_slave_sql(MYSQL *mysql_con)
66416676
*/
66426677
while ((row= mysql_fetch_row(slave_status_res)))
66436678
{
6644-
char query[26 + NAME_CHAR_LEN]; // sizeof(snprintf)
6679+
char query[38 + NAME_CHAR_LEN]; // sizeof(snprintf)
66456680
snprintf(query, sizeof(query),
6646-
"START SLAVE '%.*s' SQL_THREAD",
6647-
NAME_CHAR_LEN, row[/* Connection_name */ 0]);
6681+
"START SLAVE SQL_THREAD FOR CHANNEL '%.*s'",
6682+
NAME_CHAR_LEN, row[slave_status_indices.connection_name]);
66486683
if ((have_info_schema_slave_status ||
6649-
strcmp(row[/* Slave_SQL_Running */ 13], "No")
6684+
strcmp(row[slave_status_indices.slave_sql_running], "No")
66506685
) && mysql_query_with_error_report(mysql_con, nullptr, query))
66516686
{
66526687
fprintf(stderr, "%s: Error: Unable to start slave '%s'\n",
@@ -7675,12 +7710,7 @@ int main(int argc, char **argv)
76757710
init_connection_pool(opt_parallel);
76767711

76777712
/* Check if the server support multi source */
7678-
unsigned long server_version= mysql_get_server_version(mysql);
7679-
if (server_version >= 100000)
7680-
{
7681-
have_info_schema_slave_status= server_version >= 110600;
7682-
have_mariadb_gtid= 1;
7683-
}
7713+
have_mariadb_gtid= mysql_get_server_version(mysql) >= 100000;
76847714

76857715
if (opt_slave_data && do_stop_slave_sql(mysql))
76867716
goto err;
@@ -7747,6 +7777,7 @@ int main(int argc, char **argv)
77477777
sizeof(master_set_gtid_pos)))
77487778
goto err;
77497779
if (opt_slave_data && do_show_slave_status(mysql,
7780+
have_mariadb_gtid,
77507781
opt_use_gtid,
77517782
slave_set_gtid_pos,
77527783
sizeof(slave_set_gtid_pos)))

0 commit comments

Comments
 (0)