Commit 2d0c579a authored by Monty's avatar Monty

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.
parent e7f55fde
...@@ -949,6 +949,7 @@ bool Master_info_index::init_all_master_info() ...@@ -949,6 +949,7 @@ bool Master_info_index::init_all_master_info()
int err_num= 0, succ_num= 0; // The number of success read Master_info int err_num= 0, succ_num= 0; // The number of success read Master_info
char sign[MAX_CONNECTION_NAME+1]; char sign[MAX_CONNECTION_NAME+1];
File index_file_nr; File index_file_nr;
THD *thd;
DBUG_ENTER("init_all_master_info"); DBUG_ENTER("init_all_master_info");
DBUG_ASSERT(master_info_index); DBUG_ASSERT(master_info_index);
...@@ -980,6 +981,10 @@ bool Master_info_index::init_all_master_info() ...@@ -980,6 +981,10 @@ bool Master_info_index::init_all_master_info()
DBUG_RETURN(1); DBUG_RETURN(1);
} }
thd= new THD; /* Needed by start_slave_threads */
thd->thread_stack= (char*) &thd;
thd->store_globals();
reinit_io_cache(&index_file, READ_CACHE, 0L,0,0); reinit_io_cache(&index_file, READ_CACHE, 0L,0,0);
while (!init_strvar_from_file(sign, sizeof(sign), while (!init_strvar_from_file(sign, sizeof(sign),
&index_file, NULL)) &index_file, NULL))
...@@ -995,7 +1000,7 @@ bool Master_info_index::init_all_master_info() ...@@ -995,7 +1000,7 @@ bool Master_info_index::init_all_master_info()
mi->error()) mi->error())
{ {
delete mi; delete mi;
DBUG_RETURN(1); goto error;
} }
init_thread_mask(&thread_mask,mi,0 /*not inverse*/); init_thread_mask(&thread_mask,mi,0 /*not inverse*/);
...@@ -1024,7 +1029,7 @@ bool Master_info_index::init_all_master_info() ...@@ -1024,7 +1029,7 @@ bool Master_info_index::init_all_master_info()
{ {
/* Master_info is not in HASH; Add it */ /* Master_info is not in HASH; Add it */
if (master_info_index->add_master_info(mi, FALSE)) if (master_info_index->add_master_info(mi, FALSE))
DBUG_RETURN(1); goto error;
succ_num++; succ_num++;
mi->unlock_slave_threads(); mi->unlock_slave_threads();
} }
...@@ -1059,13 +1064,13 @@ bool Master_info_index::init_all_master_info() ...@@ -1059,13 +1064,13 @@ bool Master_info_index::init_all_master_info()
/* Master_info was not registered; add it */ /* Master_info was not registered; add it */
if (master_info_index->add_master_info(mi, FALSE)) if (master_info_index->add_master_info(mi, FALSE))
DBUG_RETURN(1); goto error;
succ_num++; succ_num++;
if (!opt_skip_slave_start) if (!opt_skip_slave_start)
{ {
if (start_slave_threads(1 /* need mutex */, if (start_slave_threads(1 /* need mutex */,
0 /* no wait for start*/, 1 /* wait for start*/,
mi, mi,
buf_master_info_file, buf_master_info_file,
buf_relay_log_info_file, buf_relay_log_info_file,
...@@ -1084,6 +1089,8 @@ bool Master_info_index::init_all_master_info() ...@@ -1084,6 +1089,8 @@ bool Master_info_index::init_all_master_info()
mi->unlock_slave_threads(); mi->unlock_slave_threads();
} }
} }
thd->reset_globals();
delete thd;
if (!err_num) // No Error on read Master_info if (!err_num) // No Error on read Master_info
{ {
...@@ -1091,16 +1098,19 @@ bool Master_info_index::init_all_master_info() ...@@ -1091,16 +1098,19 @@ bool Master_info_index::init_all_master_info()
sql_print_information("Reading of all Master_info entries succeded"); sql_print_information("Reading of all Master_info entries succeded");
DBUG_RETURN(0); DBUG_RETURN(0);
} }
else if (succ_num) // Have some Error and some Success if (succ_num) // Have some Error and some Success
{ {
sql_print_warning("Reading of some Master_info entries failed"); sql_print_warning("Reading of some Master_info entries failed");
DBUG_RETURN(2); DBUG_RETURN(2);
} }
else // All failed
{ sql_print_error("Reading of all Master_info entries failed!");
sql_print_error("Reading of all Master_info entries failed!"); DBUG_RETURN(1);
DBUG_RETURN(1);
} error:
thd->reset_globals();
delete thd;
DBUG_RETURN(1);
} }
......
...@@ -421,12 +421,21 @@ int init_slave() ...@@ -421,12 +421,21 @@ int init_slave()
if (active_mi->host[0] && !opt_skip_slave_start) if (active_mi->host[0] && !opt_skip_slave_start)
{ {
if (start_slave_threads(1 /* need mutex */, int error;
0 /* no wait for start*/, THD *thd= new THD;
active_mi, thd->thread_stack= (char*) &thd;
master_info_file, thd->store_globals();
relay_log_info_file,
SLAVE_IO | SLAVE_SQL)) error= start_slave_threads(1 /* need mutex */,
1 /* wait for start*/,
active_mi,
master_info_file,
relay_log_info_file,
SLAVE_IO | SLAVE_SQL);
thd->reset_globals();
delete thd;
if (error)
{ {
sql_print_error("Failed to create slave threads"); sql_print_error("Failed to create slave threads");
goto err; goto err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment