summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeemu Ollakka <teemu.ollakka@galeracluster.com>2019-02-12 20:12:05 +0200
committerJan Lindström <jan.lindstrom@mariadb.com>2019-02-19 17:09:19 +0200
commit7ae685d032fbb885e59a547e445b79cb6220e417 (patch)
tree2cf91083bb0079f7dc536e97a49f64d637894a30
parent48554fe2db9643f0d611214b6719af7240653886 (diff)
downloadmariadb-git-7ae685d032fbb885e59a547e445b79cb6220e417.tar.gz
Fixed replaying bugs found with multimaster load
The replayer did not signal replaying waiters. Added mysql_cond_broadcast() after replaying is over. Assertion on client error failed after replay attempt failed due to certification failure. At this point the transaction does not go through client state, so the client error cannot be overridden. Assign ER_LOCK_DEADLOCK to thd directly instead. Use timed cond wait when waiting for replayers to finish and check if the transaction has been BF aborted during the wait.
-rw-r--r--sql/wsrep_client_service.cc11
-rw-r--r--sql/wsrep_high_priority_service.cc2
m---------wsrep-lib0
3 files changed, 10 insertions, 3 deletions
diff --git a/sql/wsrep_client_service.cc b/sql/wsrep_client_service.cc
index 62b90cc032f..dd6d7d0bcfb 100644
--- a/sql/wsrep_client_service.cc
+++ b/sql/wsrep_client_service.cc
@@ -260,6 +260,7 @@ enum wsrep::provider::status Wsrep_client_service::replay()
replayer_service.replay_status(ret);
mysql_mutex_lock(&LOCK_wsrep_replaying);
--wsrep_replaying;
+ mysql_cond_broadcast(&COND_wsrep_replaying);
mysql_mutex_unlock(&LOCK_wsrep_replaying);
return ret;
}
@@ -269,9 +270,15 @@ void Wsrep_client_service::wait_for_replayers(wsrep::unique_lock<wsrep::mutex>&
DBUG_ASSERT(m_thd == current_thd);
lock.unlock();
mysql_mutex_lock(&LOCK_wsrep_replaying);
- while (wsrep_replaying > 0)
+ /* We need to check if the THD is BF aborted during condition wait.
+ Because the aborter does not know which condition this thread is waiting,
+ use timed wait and check if the THD is BF aborted in the loop. */
+ while (wsrep_replaying > 0 && !wsrep_is_bf_aborted(m_thd))
{
- mysql_cond_wait(&COND_wsrep_replaying, &LOCK_wsrep_replaying);
+ struct timespec wait_time;
+ set_timespec_nsec(wait_time, 10000000L);
+ mysql_cond_timedwait(&COND_wsrep_replaying, &LOCK_wsrep_replaying,
+ &wait_time);
}
mysql_mutex_unlock(&LOCK_wsrep_replaying);
lock.lock();
diff --git a/sql/wsrep_high_priority_service.cc b/sql/wsrep_high_priority_service.cc
index f1637e2ece0..64fe4ce52fe 100644
--- a/sql/wsrep_high_priority_service.cc
+++ b/sql/wsrep_high_priority_service.cc
@@ -598,7 +598,7 @@ Wsrep_replayer_service::~Wsrep_replayer_service()
}
else if (m_replay_status == wsrep::provider::error_certification_failed)
{
- DBUG_ASSERT(thd->wsrep_cs().current_error() == wsrep::e_deadlock_error);
+ wsrep_override_error(thd, ER_LOCK_DEADLOCK);
}
else
{
diff --git a/wsrep-lib b/wsrep-lib
-Subproject 92024c7d502b716c8c0ca5e2b9524b43d3a5378
+Subproject 0b09871ad5a10a773c4cbad28e681021d8d234b