diff options
Diffstat (limited to 'storage/innobase/dict/dict0stats_bg.cc')
-rw-r--r-- | storage/innobase/dict/dict0stats_bg.cc | 52 |
1 files changed, 27 insertions, 25 deletions
diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc index a66aac22..b0c34dc6 100644 --- a/storage/innobase/dict/dict0stats_bg.cc +++ b/storage/innobase/dict/dict0stats_bg.cc @@ -69,6 +69,8 @@ static recalc_pool_t recalc_pool; /** Whether the global data structures have been initialized */ static bool stats_initialised; +static THD *dict_stats_thd; + /*****************************************************************//** Free the resources occupied by the recalc pool, called once during thread de-initialization. */ @@ -90,6 +92,9 @@ static void dict_stats_recalc_pool_deinit() defrag_pool_t defrag_empty_pool; recalc_pool.swap(recalc_empty_pool); defrag_pool.swap(defrag_empty_pool); + + if (dict_stats_thd) + destroy_background_thd(dict_stats_thd); } /*****************************************************************//** @@ -361,52 +366,50 @@ done: { ut_ad(i->state == recalc::IN_PROGRESS); recalc_pool.erase(i); - const bool reschedule= !update_now && recalc_pool.empty(); if (err == DB_SUCCESS_LOCKED_REC) recalc_pool.emplace_back(recalc{table_id, recalc::IDLE}); mysql_mutex_unlock(&recalc_pool_mutex); - if (reschedule) - dict_stats_schedule(MIN_RECALC_INTERVAL * 1000); } return update_now; } -static tpool::timer* dict_stats_timer; -static std::mutex dict_stats_mutex; +/** Check if the recalc pool is empty. */ +static bool is_recalc_pool_empty() +{ + mysql_mutex_lock(&recalc_pool_mutex); + bool empty= recalc_pool.empty(); + mysql_mutex_unlock(&recalc_pool_mutex); + return empty; +} +static tpool::timer* dict_stats_timer; static void dict_stats_func(void*) { - THD *thd= innobase_create_background_thd("InnoDB statistics"); - set_current_thd(thd); - while (dict_stats_process_entry_from_recalc_pool(thd)) {} - dict_defrag_process_entries_from_defrag_pool(thd); + if (!dict_stats_thd) + dict_stats_thd= innobase_create_background_thd("InnoDB statistics"); + set_current_thd(dict_stats_thd); + + while (dict_stats_process_entry_from_recalc_pool(dict_stats_thd)) {} + dict_defrag_process_entries_from_defrag_pool(dict_stats_thd); + + innobase_reset_background_thd(dict_stats_thd); set_current_thd(nullptr); - destroy_background_thd(thd); + if (!is_recalc_pool_empty()) + dict_stats_schedule(MIN_RECALC_INTERVAL * 1000); } void dict_stats_start() { - std::lock_guard<std::mutex> lk(dict_stats_mutex); - if (!dict_stats_timer) - dict_stats_timer= srv_thread_pool->create_timer(dict_stats_func); + DBUG_ASSERT(!dict_stats_timer); + dict_stats_timer= srv_thread_pool->create_timer(dict_stats_func); } static void dict_stats_schedule(int ms) { - std::unique_lock<std::mutex> lk(dict_stats_mutex, std::defer_lock); - /* - Use try_lock() to avoid deadlock in dict_stats_shutdown(), which - uses dict_stats_mutex too. If there is simultaneous timer reschedule, - the first one will win, which is fine. - */ - if (!lk.try_lock()) - { - return; - } - if (dict_stats_timer) + if(dict_stats_timer) dict_stats_timer->set_time(ms,0); } @@ -418,7 +421,6 @@ void dict_stats_schedule_now() /** Shut down the dict_stats_thread. */ void dict_stats_shutdown() { - std::lock_guard<std::mutex> lk(dict_stats_mutex); delete dict_stats_timer; dict_stats_timer= 0; } |