diff options
author | Vladislav Vaintroub <wlad@mariadb.com> | 2019-11-25 14:41:13 +0100 |
---|---|---|
committer | Vladislav Vaintroub <wlad@mariadb.com> | 2019-11-25 15:02:08 +0100 |
commit | 7c7f9bef28aa566557da31402142f6dd8298ddd2 (patch) | |
tree | 7d28adb2c99e8a0fe23ca1b85230c355b06dcb5f | |
parent | 312569e2fd79a6582161900e726847ad688ee3b0 (diff) | |
download | mariadb-git-mariadb-10.5.0.tar.gz |
Fix shutdown hang in dict_stats , caused by MDEV-16264mariadb-10.5.0
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.
-rw-r--r-- | storage/innobase/dict/dict0stats_bg.cc | 11 |
1 files changed, 10 insertions, 1 deletions
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<std::mutex> lk(dict_stats_mutex); + 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) dict_stats_timer->set_time(ms,0); } |