summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2017-03-06 16:25:01 +0200
committerMonty <monty@mariadb.org>2017-03-16 14:21:33 +0200
commit2d0c579a86fb9f976ab447e5799084e39a615329 (patch)
tree3e624fc1bd4f78be0d65c79ad093260058c69251
parente7f55fde8817508b77bef0ec2352a02e1f0ea2c4 (diff)
downloadmariadb-git-2d0c579a86fb9f976ab447e5799084e39a615329.tar.gz
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.
-rw-r--r--sql/rpl_mi.cc30
-rw-r--r--sql/slave.cc21
2 files changed, 35 insertions, 16 deletions
diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc
index fd501e62898..bff0abe8198 100644
--- a/sql/rpl_mi.cc
+++ b/sql/rpl_mi.cc
@@ -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
char sign[MAX_CONNECTION_NAME+1];
File index_file_nr;
+ THD *thd;
DBUG_ENTER("init_all_master_info");
DBUG_ASSERT(master_info_index);
@@ -980,6 +981,10 @@ bool Master_info_index::init_all_master_info()
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);
while (!init_strvar_from_file(sign, sizeof(sign),
&index_file, NULL))
@@ -995,7 +1000,7 @@ bool Master_info_index::init_all_master_info()
mi->error())
{
delete mi;
- DBUG_RETURN(1);
+ goto error;
}
init_thread_mask(&thread_mask,mi,0 /*not inverse*/);
@@ -1024,7 +1029,7 @@ bool Master_info_index::init_all_master_info()
{
/* Master_info is not in HASH; Add it */
if (master_info_index->add_master_info(mi, FALSE))
- DBUG_RETURN(1);
+ goto error;
succ_num++;
mi->unlock_slave_threads();
}
@@ -1059,13 +1064,13 @@ bool Master_info_index::init_all_master_info()
/* Master_info was not registered; add it */
if (master_info_index->add_master_info(mi, FALSE))
- DBUG_RETURN(1);
+ goto error;
succ_num++;
if (!opt_skip_slave_start)
{
if (start_slave_threads(1 /* need mutex */,
- 0 /* no wait for start*/,
+ 1 /* wait for start*/,
mi,
buf_master_info_file,
buf_relay_log_info_file,
@@ -1084,6 +1089,8 @@ bool Master_info_index::init_all_master_info()
mi->unlock_slave_threads();
}
}
+ thd->reset_globals();
+ delete thd;
if (!err_num) // No Error on read Master_info
{
@@ -1091,16 +1098,19 @@ bool Master_info_index::init_all_master_info()
sql_print_information("Reading of all Master_info entries succeded");
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");
DBUG_RETURN(2);
}
- else // All failed
- {
- sql_print_error("Reading of all Master_info entries failed!");
- DBUG_RETURN(1);
- }
+
+ sql_print_error("Reading of all Master_info entries failed!");
+ DBUG_RETURN(1);
+
+error:
+ thd->reset_globals();
+ delete thd;
+ DBUG_RETURN(1);
}
diff --git a/sql/slave.cc b/sql/slave.cc
index 36d28382c56..70b1c5b025e 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -421,12 +421,21 @@ int init_slave()
if (active_mi->host[0] && !opt_skip_slave_start)
{
- if (start_slave_threads(1 /* need mutex */,
- 0 /* no wait for start*/,
- active_mi,
- master_info_file,
- relay_log_info_file,
- SLAVE_IO | SLAVE_SQL))
+ int error;
+ THD *thd= new THD;
+ thd->thread_stack= (char*) &thd;
+ thd->store_globals();
+
+ 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");
goto err;