summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-05-16 16:35:33 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2018-05-16 16:35:33 +0300
commita4e7800701d0764fe4cbb85b81d7c7cb54677334 (patch)
tree7db65106dfe46274dd4a2042bf202cb8b1dbda82
parentebc24950e6d107b2958887cc03fe67db1073ccf2 (diff)
downloadmariadb-git-a4e7800701d0764fe4cbb85b81d7c7cb54677334.tar.gz
MDEV-13779 InnoDB fails to shut down purge workers, causing hang
srv_purge_coordinator_thread(): Wait for all purge worker threads to actually exit. An analysis of a core dump of a hung 10.3 server revealed that one srv_worker_thread did not exit, even though the purge coordinator had exited. This caused kill_server_thread and mysqld_main to wait indefinitely. The main InnoDB shutdown was never called, because unireg_end() was never called.
-rw-r--r--storage/innobase/srv/srv0srv.cc14
1 files changed, 12 insertions, 2 deletions
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 5f93ff7cd7c..802271bb96f 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -2876,8 +2876,18 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
#endif /* UNIV_DEBUG_THREAD_CREATION */
/* Ensure that all the worker threads quit. */
- if (srv_n_purge_threads > 1) {
- srv_release_threads(SRV_WORKER, srv_n_purge_threads - 1);
+ if (ulint n_workers = srv_n_purge_threads - 1) {
+ const srv_slot_t* slot;
+ const srv_slot_t* const end = &srv_sys.sys_threads[
+ srv_sys.n_sys_threads];
+
+ do {
+ srv_release_threads(SRV_WORKER, n_workers);
+ srv_sys_mutex_enter();
+ for (slot = &srv_sys.sys_threads[2];
+ !slot++->in_use && slot < end; );
+ srv_sys_mutex_exit();
+ } while (slot < end);
}
innobase_destroy_background_thd(thd);