From c6a60f6d79862bd82d517a25c6e13e6d141173b6 Mon Sep 17 00:00:00 2001 From: Kristian Nielsen Date: Wed, 20 Aug 2014 10:59:39 +0200 Subject: [PATCH] MDEV-6321: close_temporary_tables() in format description event not serialised correctly After-review fixes. Mainly catching if the wait in wait_for_workers_idle() is aborted due to kill. In this case, we should return an error and not proceed to execute the format description event, as other threads might still be running for a bit until the error is caught in all threads. --- sql/rpl_parallel.cc | 15 +++++++++++---- sql/rpl_parallel.h | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc index 21234d7fd38..038abb351ea 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -1689,11 +1689,15 @@ rpl_parallel_entry::queue_master_restart(rpl_group_info *rgi, } -void +int rpl_parallel::wait_for_workers_idle(THD *thd) { uint32 i, max_i; + /* + The domain_hash is only accessed by the SQL driver thread, so it is safe + to iterate over without a lock. + */ max_i= domain_hash.records; for (i= 0; i < max_i; ++i) { @@ -1712,10 +1716,13 @@ rpl_parallel::wait_for_workers_idle(THD *thd) mysql_mutex_unlock(&e->LOCK_parallel_entry); if (active) { - my_orderer.wait_for_prior_commit(thd); + int err= my_orderer.wait_for_prior_commit(thd); thd->wait_for_commit_ptr= NULL; + if (err) + return err; } } + return 0; } @@ -1804,12 +1811,12 @@ rpl_parallel::do_event(rpl_group_info *serial_rgi, Log_event *ev, event group (if any), as such event group signifies an incompletely written group cut short by a master crash, and must be rolled back. */ - if (current->queue_master_restart(serial_rgi, fdev)) + if (current->queue_master_restart(serial_rgi, fdev) || + wait_for_workers_idle(rli->sql_driver_thd)) { delete ev; return 1; } - wait_for_workers_idle(rli->sql_driver_thd); } } diff --git a/sql/rpl_parallel.h b/sql/rpl_parallel.h index befe08b3d9b..b114ee4ebcb 100644 --- a/sql/rpl_parallel.h +++ b/sql/rpl_parallel.h @@ -244,7 +244,7 @@ struct rpl_parallel { void wait_for_done(THD *thd, Relay_log_info *rli); void stop_during_until(); bool workers_idle(); - void wait_for_workers_idle(THD *thd); + int wait_for_workers_idle(THD *thd); int do_event(rpl_group_info *serial_rgi, Log_event *ev, ulonglong event_size); };