summaryrefslogtreecommitdiff
path: root/sql/wsrep_client_service.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/wsrep_client_service.cc')
-rw-r--r--sql/wsrep_client_service.cc36
1 files changed, 27 insertions, 9 deletions
diff --git a/sql/wsrep_client_service.cc b/sql/wsrep_client_service.cc
index c042a1ea051..b182691c593 100644
--- a/sql/wsrep_client_service.cc
+++ b/sql/wsrep_client_service.cc
@@ -250,20 +250,38 @@ void Wsrep_client_service::will_replay()
enum wsrep::provider::status Wsrep_client_service::replay()
{
+
DBUG_ASSERT(m_thd == current_thd);
- Wsrep_replayer_service replayer_service(m_thd);
- wsrep::provider& provider(m_thd->wsrep_cs().provider());
- mysql_mutex_lock(&m_thd->LOCK_thd_data);
- m_thd->killed= NOT_KILLED;
- mysql_mutex_unlock(&m_thd->LOCK_thd_data);
- enum wsrep::provider::status ret=
- provider.replay(m_thd->wsrep_trx().ws_handle(), &replayer_service);
- replayer_service.replay_status(ret);
+ DBUG_ENTER("Wsrep_client_service::replay");
+
+ /*
+ Allocate separate THD for replaying to avoid tampering
+ original THD state during replication event applying.
+ */
+ THD *replayer_thd= new THD(true, true);
+ replayer_thd->thread_stack= m_thd->thread_stack;
+ replayer_thd->real_id= pthread_self();
+ replayer_thd->prior_thr_create_utime=
+ replayer_thd->start_utime= microsecond_interval_timer();
+ replayer_thd->set_command(COM_SLEEP);
+ replayer_thd->reset_for_next_command(true);
+
+ enum wsrep::provider::status ret;
+ {
+ Wsrep_replayer_service replayer_service(replayer_thd, m_thd);
+ wsrep::provider& provider(replayer_thd->wsrep_cs().provider());
+ ret= provider.replay(replayer_thd->wsrep_trx().ws_handle(),
+ &replayer_service);
+ replayer_service.replay_status(ret);
+ }
+
+ delete replayer_thd;
+
mysql_mutex_lock(&LOCK_wsrep_replaying);
--wsrep_replaying;
mysql_cond_broadcast(&COND_wsrep_replaying);
mysql_mutex_unlock(&LOCK_wsrep_replaying);
- return ret;
+ DBUG_RETURN(ret);
}
void Wsrep_client_service::wait_for_replayers(wsrep::unique_lock<wsrep::mutex>& lock)