summaryrefslogtreecommitdiffstats
path: root/storage/innobase/dict/dict0stats_bg.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/dict/dict0stats_bg.cc')
-rw-r--r--storage/innobase/dict/dict0stats_bg.cc52
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;
}