summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-05-14 18:04:25 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2018-05-14 18:19:20 +0300
commitfb5d5794623af1e6bff2ba7f6c7142770fa5e9d9 (patch)
tree84293cd294697990a4829f94290f31d0478b9a37
parent16a8a241c297a4ae683523e68518aa85a129daea (diff)
downloadmariadb-git-fb5d5794623af1e6bff2ba7f6c7142770fa5e9d9.tar.gz
MDEV-13987 Hang in FLUSH TABLES...FOR EXPORT
trx_purge_stop(): Release purge_sys->latch before attempting to wake up the purge threads, so that they can actually wake up. This is a regression of commit a13a636c74d9778ec0430ec963dcfd1614f7c81e which attempted to fix MDEV-11802 by ensuring that srv_purge_wakeup() will actually wait until all purge threads wake up. Due to the purge_sys->latch, the threads might never wake up, because some purge threads could end up waiting for purge_sys->latch in trx_undo_prev_version_build() while holding dict_operation_lock in shared mode. This in turn would block any DDL operations, the InnoDB master thread, and InnoDB shutdown.
-rw-r--r--storage/innobase/srv/srv0srv.cc1
-rw-r--r--storage/innobase/trx/trx0purge.cc2
2 files changed, 2 insertions, 1 deletions
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 81e3b83af05..5f93ff7cd7c 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -2932,6 +2932,7 @@ void
srv_purge_wakeup()
{
ut_ad(!srv_read_only_mode);
+ ut_ad(!sync_check_iterate(sync_check()));
if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND) {
return;
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index 16ee1d2e8e8..603b967484e 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -1781,8 +1781,8 @@ unlock:
const int64_t sig_count = os_event_reset(purge_sys->event);
purge_sys->state = PURGE_STATE_STOP;
- srv_purge_wakeup();
rw_lock_x_unlock(&purge_sys->latch);
+ srv_purge_wakeup();
/* Wait for purge coordinator to signal that it
is suspended. */
os_event_wait_low(purge_sys->event, sig_count);