diff options
author | Monty <monty@mariadb.org> | 2017-03-06 16:25:01 +0200 |
---|---|---|
committer | Monty <monty@mariadb.org> | 2017-03-16 14:21:33 +0200 |
commit | 2d0c579a86fb9f976ab447e5799084e39a615329 (patch) | |
tree | 3e624fc1bd4f78be0d65c79ad093260058c69251 | |
parent | e7f55fde8817508b77bef0ec2352a02e1f0ea2c4 (diff) | |
download | mariadb-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.cc | 30 | ||||
-rw-r--r-- | sql/slave.cc | 21 |
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; |