Skip to content

Commit 2d0c579

Browse files
committed
Wait for slave threads to start during startup
- Before this patch during startup all slave threads was started without any check that they had started properly. - If one did a START SLAVE, STOP SLAVE or CHANGE MASTER as first command to the server there was a chance that server could access structures that where not properly initialized which could lead to crashes in Log_event::read_log_event - Fixed by waiting for slave threads to start up properly also during server startup, like we do with START SLAVE.
1 parent e7f55fd commit 2d0c579

File tree

2 files changed

+35
-16
lines changed

2 files changed

+35
-16
lines changed

sql/rpl_mi.cc

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,7 @@ bool Master_info_index::init_all_master_info()
949949
int err_num= 0, succ_num= 0; // The number of success read Master_info
950950
char sign[MAX_CONNECTION_NAME+1];
951951
File index_file_nr;
952+
THD *thd;
952953
DBUG_ENTER("init_all_master_info");
953954

954955
DBUG_ASSERT(master_info_index);
@@ -980,6 +981,10 @@ bool Master_info_index::init_all_master_info()
980981
DBUG_RETURN(1);
981982
}
982983

984+
thd= new THD; /* Needed by start_slave_threads */
985+
thd->thread_stack= (char*) &thd;
986+
thd->store_globals();
987+
983988
reinit_io_cache(&index_file, READ_CACHE, 0L,0,0);
984989
while (!init_strvar_from_file(sign, sizeof(sign),
985990
&index_file, NULL))
@@ -995,7 +1000,7 @@ bool Master_info_index::init_all_master_info()
9951000
mi->error())
9961001
{
9971002
delete mi;
998-
DBUG_RETURN(1);
1003+
goto error;
9991004
}
10001005

10011006
init_thread_mask(&thread_mask,mi,0 /*not inverse*/);
@@ -1024,7 +1029,7 @@ bool Master_info_index::init_all_master_info()
10241029
{
10251030
/* Master_info is not in HASH; Add it */
10261031
if (master_info_index->add_master_info(mi, FALSE))
1027-
DBUG_RETURN(1);
1032+
goto error;
10281033
succ_num++;
10291034
mi->unlock_slave_threads();
10301035
}
@@ -1059,13 +1064,13 @@ bool Master_info_index::init_all_master_info()
10591064

10601065
/* Master_info was not registered; add it */
10611066
if (master_info_index->add_master_info(mi, FALSE))
1062-
DBUG_RETURN(1);
1067+
goto error;
10631068
succ_num++;
10641069

10651070
if (!opt_skip_slave_start)
10661071
{
10671072
if (start_slave_threads(1 /* need mutex */,
1068-
0 /* no wait for start*/,
1073+
1 /* wait for start*/,
10691074
mi,
10701075
buf_master_info_file,
10711076
buf_relay_log_info_file,
@@ -1084,23 +1089,28 @@ bool Master_info_index::init_all_master_info()
10841089
mi->unlock_slave_threads();
10851090
}
10861091
}
1092+
thd->reset_globals();
1093+
delete thd;
10871094

10881095
if (!err_num) // No Error on read Master_info
10891096
{
10901097
if (global_system_variables.log_warnings > 1)
10911098
sql_print_information("Reading of all Master_info entries succeded");
10921099
DBUG_RETURN(0);
10931100
}
1094-
else if (succ_num) // Have some Error and some Success
1101+
if (succ_num) // Have some Error and some Success
10951102
{
10961103
sql_print_warning("Reading of some Master_info entries failed");
10971104
DBUG_RETURN(2);
10981105
}
1099-
else // All failed
1100-
{
1101-
sql_print_error("Reading of all Master_info entries failed!");
1102-
DBUG_RETURN(1);
1103-
}
1106+
1107+
sql_print_error("Reading of all Master_info entries failed!");
1108+
DBUG_RETURN(1);
1109+
1110+
error:
1111+
thd->reset_globals();
1112+
delete thd;
1113+
DBUG_RETURN(1);
11041114
}
11051115

11061116

sql/slave.cc

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -421,12 +421,21 @@ int init_slave()
421421

422422
if (active_mi->host[0] && !opt_skip_slave_start)
423423
{
424-
if (start_slave_threads(1 /* need mutex */,
425-
0 /* no wait for start*/,
426-
active_mi,
427-
master_info_file,
428-
relay_log_info_file,
429-
SLAVE_IO | SLAVE_SQL))
424+
int error;
425+
THD *thd= new THD;
426+
thd->thread_stack= (char*) &thd;
427+
thd->store_globals();
428+
429+
error= start_slave_threads(1 /* need mutex */,
430+
1 /* wait for start*/,
431+
active_mi,
432+
master_info_file,
433+
relay_log_info_file,
434+
SLAVE_IO | SLAVE_SQL);
435+
436+
thd->reset_globals();
437+
delete thd;
438+
if (error)
430439
{
431440
sql_print_error("Failed to create slave threads");
432441
goto err;

0 commit comments

Comments
 (0)