diff options
author | Kristian Nielsen <knielsen@knielsen-hq.org> | 2015-04-17 15:18:44 +0200 |
---|---|---|
committer | Kristian Nielsen <knielsen@knielsen-hq.org> | 2015-04-17 15:18:44 +0200 |
commit | 167332597f03f73057fbb4684687a013596181bd (patch) | |
tree | 1256610eb3a54a2e6f847badea452e3fc274a5c0 /sql | |
parent | 8125db1d9ae489162f08560f42c60c10a316afbc (diff) | |
parent | 702fdc52fa02c5f20004d169ad48494122d8ffed (diff) | |
download | mariadb-git-167332597f03f73057fbb4684687a013596181bd.tar.gz |
Merge 10.0 -> 10.1.
Conflicts:
mysql-test/suite/multi_source/multisource.result
sql/sql_base.cc
Diffstat (limited to 'sql')
-rw-r--r-- | sql/rpl_mi.cc | 28 | ||||
-rw-r--r-- | sql/rpl_mi.h | 1 | ||||
-rw-r--r-- | sql/rpl_parallel.cc | 63 | ||||
-rw-r--r-- | sql/rpl_parallel.h | 6 | ||||
-rw-r--r-- | sql/slave.cc | 9 | ||||
-rw-r--r-- | sql/sql_base.cc | 19 | ||||
-rw-r--r-- | sql/sys_vars.cc | 8 |
7 files changed, 85 insertions, 49 deletions
diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index 8ce67bbf4b8..a56a4e5dc7b 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -1368,7 +1368,7 @@ bool Master_info_index::remove_master_info(LEX_STRING *name) bool Master_info_index::give_error_if_slave_running() { - DBUG_ENTER("warn_if_slave_running"); + DBUG_ENTER("give_error_if_slave_running"); mysql_mutex_assert_owner(&LOCK_active_mi); if (!this) // master_info_index is set to NULL on server shutdown return TRUE; @@ -1389,6 +1389,32 @@ bool Master_info_index::give_error_if_slave_running() /** + Master_info_index::any_slave_sql_running() + + The LOCK_active_mi must be held while calling this function. + + @return + TRUE If some slave SQL thread is running. + FALSE No slave SQL thread is running +*/ + +bool Master_info_index::any_slave_sql_running() +{ + DBUG_ENTER("any_slave_sql_running"); + if (!this) // master_info_index is set to NULL on server shutdown + return TRUE; + + for (uint i= 0; i< master_info_hash.records; ++i) + { + Master_info *mi= (Master_info *)my_hash_element(&master_info_hash, i); + if (mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN) + DBUG_RETURN(TRUE); + } + DBUG_RETURN(FALSE); +} + + +/** Master_info_index::start_all_slaves() Start all slaves that was not running. diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index b74b9cb42b3..7ba64a9dc92 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -345,6 +345,7 @@ public: Master_info *get_master_info(const LEX_STRING *connection_name, Sql_condition::enum_warning_level warning); bool give_error_if_slave_running(); + bool any_slave_sql_running(); bool start_all_slaves(THD *thd); bool stop_all_slaves(THD *thd); }; diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc index 4212a0e09d5..7256d274551 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -1021,9 +1021,9 @@ dealloc_gco(group_commit_orderer *gco) } -int +static int rpl_parallel_change_thread_count(rpl_parallel_thread_pool *pool, - uint32 new_count, bool skip_check) + uint32 new_count) { uint32 i; rpl_parallel_thread **old_list= NULL; @@ -1069,24 +1069,6 @@ rpl_parallel_change_thread_count(rpl_parallel_thread_pool *pool, new_free_list= new_list[i]; } - if (!skip_check) - { - mysql_mutex_lock(&LOCK_active_mi); - if (master_info_index->give_error_if_slave_running()) - { - mysql_mutex_unlock(&LOCK_active_mi); - goto err; - } - if (pool->changing) - { - mysql_mutex_unlock(&LOCK_active_mi); - my_error(ER_CHANGE_SLAVE_PARALLEL_THREADS_ACTIVE, MYF(0)); - goto err; - } - pool->changing= true; - mysql_mutex_unlock(&LOCK_active_mi); - } - /* Grab each old thread in turn, and signal it to stop. @@ -1150,13 +1132,6 @@ rpl_parallel_change_thread_count(rpl_parallel_thread_pool *pool, mysql_mutex_unlock(&pool->threads[i]->LOCK_rpl_thread); } - if (!skip_check) - { - mysql_mutex_lock(&LOCK_active_mi); - pool->changing= false; - mysql_mutex_unlock(&LOCK_active_mi); - } - mysql_mutex_lock(&pool->LOCK_rpl_thread_pool); mysql_cond_broadcast(&pool->COND_rpl_thread_pool); mysql_mutex_unlock(&pool->LOCK_rpl_thread_pool); @@ -1183,16 +1158,26 @@ err: } my_free(new_list); } - if (!skip_check) - { - mysql_mutex_lock(&LOCK_active_mi); - pool->changing= false; - mysql_mutex_unlock(&LOCK_active_mi); - } return 1; } +int +rpl_parallel_activate_pool(rpl_parallel_thread_pool *pool) +{ + if (!pool->count) + return rpl_parallel_change_thread_count(pool, opt_slave_parallel_threads); + return 0; +} + + +int +rpl_parallel_inactivate_pool(rpl_parallel_thread_pool *pool) +{ + return rpl_parallel_change_thread_count(pool, 0); +} + + void rpl_parallel_thread::batch_free() { @@ -1435,7 +1420,7 @@ rpl_parallel_thread::loc_free_gco(group_commit_orderer *gco) rpl_parallel_thread_pool::rpl_parallel_thread_pool() - : count(0), threads(0), free_list(0), changing(false), inited(false) + : count(0), threads(0), free_list(0), inited(false) { } @@ -1450,10 +1435,14 @@ rpl_parallel_thread_pool::init(uint32 size) mysql_mutex_init(key_LOCK_rpl_thread_pool, &LOCK_rpl_thread_pool, MY_MUTEX_INIT_SLOW); mysql_cond_init(key_COND_rpl_thread_pool, &COND_rpl_thread_pool, NULL); - changing= false; inited= true; - return rpl_parallel_change_thread_count(this, size, true); + /* + The pool is initially empty. Threads will be spawned when a slave SQL + thread is started. + */ + + return 0; } @@ -1462,7 +1451,7 @@ rpl_parallel_thread_pool::destroy() { if (!inited) return; - rpl_parallel_change_thread_count(this, 0, true); + rpl_parallel_change_thread_count(this, 0); mysql_mutex_destroy(&LOCK_rpl_thread_pool); mysql_cond_destroy(&COND_rpl_thread_pool); inited= false; diff --git a/sql/rpl_parallel.h b/sql/rpl_parallel.h index cddc8e5dd07..4734f0ca51e 100644 --- a/sql/rpl_parallel.h +++ b/sql/rpl_parallel.h @@ -227,7 +227,6 @@ struct rpl_parallel_thread_pool { struct rpl_parallel_thread *free_list; mysql_mutex_t LOCK_rpl_thread_pool; mysql_cond_t COND_rpl_thread_pool; - bool changing; bool inited; rpl_parallel_thread_pool(); @@ -337,9 +336,8 @@ struct rpl_parallel { extern struct rpl_parallel_thread_pool global_rpl_thread_pool; -extern int rpl_parallel_change_thread_count(rpl_parallel_thread_pool *pool, - uint32 new_count, - bool skip_check= false); +extern int rpl_parallel_activate_pool(rpl_parallel_thread_pool *pool); +extern int rpl_parallel_inactivate_pool(rpl_parallel_thread_pool *pool); extern bool process_gtid_for_restart_pos(Relay_log_info *rli, rpl_gtid *gtid); #endif /* RPL_PARALLEL_H */ diff --git a/sql/slave.cc b/sql/slave.cc index f9ddbb53b52..928b7aad036 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -652,6 +652,10 @@ int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock) DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS); mysql_mutex_unlock(log_lock); + + if (opt_slave_parallel_threads > 0 && + !master_info_index->any_slave_sql_running()) + rpl_parallel_inactivate_pool(&global_rpl_thread_pool); } if (thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL)) { @@ -958,7 +962,10 @@ int start_slave_threads(bool need_slave_mutex, bool wait_for_start, mi); if (!error && (thread_mask & SLAVE_SQL)) { - error= start_slave_thread( + if (opt_slave_parallel_threads > 0) + error= rpl_parallel_activate_pool(&global_rpl_thread_pool); + if (!error) + error= start_slave_thread( #ifdef HAVE_PSI_INTERFACE key_thread_slave_sql, #endif diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 0e9f668722d..e3f19623b92 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5924,6 +5924,25 @@ bool open_temporary_table(THD *thd, TABLE_LIST *tl) DBUG_RETURN(FALSE); } + /* + Temporary tables are not safe for parallel replication. They were + designed to be visible to one thread only, so have no table locking. + Thus there is no protection against two conflicting transactions + committing in parallel and things like that. + + So for now, anything that uses temporary tables will be serialised + with anything before it, when using parallel replication. + + ToDo: We might be able to introduce a reference count or something + on temp tables, and have slave worker threads wait for it to reach + zero before being allowed to use the temp table. Might not be worth + it though, as statement-based replication using temporary tables is + in any case rather fragile. + */ + if (thd->rgi_slave && thd->rgi_slave->is_parallel_exec && + thd->wait_for_prior_commit()) + DBUG_RETURN(true); + #ifdef WITH_PARTITION_STORAGE_ENGINE if (tl->partition_names) { diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index cc29762c144..8304bda1347 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1787,16 +1787,12 @@ check_slave_parallel_threads(sys_var *self, THD *thd, set_var *var) static bool fix_slave_parallel_threads(sys_var *self, THD *thd, enum_var_type type) { - bool running; - bool err= false; + bool err; mysql_mutex_unlock(&LOCK_global_system_variables); mysql_mutex_lock(&LOCK_active_mi); - running= master_info_index->give_error_if_slave_running(); + err= master_info_index->give_error_if_slave_running(); mysql_mutex_unlock(&LOCK_active_mi); - if (running || rpl_parallel_change_thread_count(&global_rpl_thread_pool, - opt_slave_parallel_threads)) - err= true; mysql_mutex_lock(&LOCK_global_system_variables); return err; |