From 7c7f9bef28aa566557da31402142f6dd8298ddd2 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 25 Nov 2019 14:41:13 +0100 Subject: [PATCH] Fix shutdown hang in dict_stats , caused by MDEV-16264 dict_stats_shutdown() can hang, waiting for timer callback to finish. This happens because locks the same mutex, which can also used inside timer callback, within dict_stats_schedule() function. Fix is to make dict_stats_schedule() use mutex.try_lock() instead of mutex.lock(). In the unlikely case of simultaneous dict_stats_schedule() setting different timer delays, now the first one would win, which is fine. Important is that shutdown won't hang. --- storage/innobase/dict/dict0stats_bg.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc index ec9fb4851d1..ee26b5bd302 100644 --- a/storage/innobase/dict/dict0stats_bg.cc +++ b/storage/innobase/dict/dict0stats_bg.cc @@ -436,7 +436,16 @@ void dict_stats_start() static void dict_stats_schedule(int ms) { - std::lock_guard lk(dict_stats_mutex); + std::unique_lock 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) dict_stats_timer->set_time(ms,0); }