From 13487781d8178d8d62d35a7241592282f2e74927 Mon Sep 17 00:00:00 2001 From: Teemu Ollakka Date: Fri, 13 Jul 2018 18:33:22 +0300 Subject: [PATCH] Total order BF abort client_state method to differentiate BF aborts caused by conflicts between transactions and conflicts between TOI operations and transactions. --- include/wsrep/client_state.hpp | 17 ++++++++++++++++- include/wsrep/transaction.hpp | 8 ++++++++ src/transaction.cpp | 24 +++++++++++++++++++----- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/include/wsrep/client_state.hpp b/include/wsrep/client_state.hpp index d215653..f33fd0e 100644 --- a/include/wsrep/client_state.hpp +++ b/include/wsrep/client_state.hpp @@ -418,13 +418,28 @@ namespace wsrep // // BF aborting // + /** + * Brute force abort a transaction. This method should be + * called by a transaction which needs to BF abort a conflicting + * locally processing transaction. + */ int bf_abort(wsrep::seqno bf_seqno) { wsrep::unique_lock lock(mutex_); assert(mode_ == m_local || transaction_.is_streaming()); return transaction_.bf_abort(lock, bf_seqno); } - + /** + * Brute force abort a transaction in total order. This method + * should be called by the TOI operation which needs to + * BF abort a transaction. + */ + int total_order_bf_abort(wsrep::seqno bf_seqno) + { + wsrep::unique_lock lock(mutex_); + assert(mode_ == m_local || transaction_.is_streaming()); + return transaction_.total_order_bf_abort(lock, bf_seqno); + } /** * Adopt a streaming transaction state. This is must be * called from high_priority_service::adopt_transaction() diff --git a/include/wsrep/transaction.hpp b/include/wsrep/transaction.hpp index 0279e22..7ca1064 100644 --- a/include/wsrep/transaction.hpp +++ b/include/wsrep/transaction.hpp @@ -126,11 +126,18 @@ namespace wsrep bool bf_abort(wsrep::unique_lock& lock, wsrep::seqno bf_seqno); + bool total_order_bf_abort(wsrep::unique_lock&, + wsrep::seqno bf_seqno); bool bf_aborted() const { return (bf_abort_client_state_ != 0); } + bool bf_aborted_in_total_order() const + { + return bf_aborted_in_total_order_; + } + int flags() const { return flags_; @@ -169,6 +176,7 @@ namespace wsrep enum state bf_abort_state_; enum wsrep::provider::status bf_abort_provider_status_; int bf_abort_client_state_; + bool bf_aborted_in_total_order_; wsrep::ws_handle ws_handle_; wsrep::ws_meta ws_meta_; int flags_; diff --git a/src/transaction.cpp b/src/transaction.cpp index 8ec54c9..95ab7d8 100644 --- a/src/transaction.cpp +++ b/src/transaction.cpp @@ -93,6 +93,7 @@ wsrep::transaction::transaction( , bf_abort_state_(s_executing) , bf_abort_provider_status_() , bf_abort_client_state_() + , bf_aborted_in_total_order_() , ws_handle_() , ws_meta_() , flags_() @@ -521,7 +522,7 @@ int wsrep::transaction::before_rollback() // fall through case s_executing: // Voluntary rollback - if (is_streaming()) + if (is_streaming() && bf_aborted_in_total_order_ == false) { streaming_rollback(); } @@ -534,7 +535,7 @@ int wsrep::transaction::before_rollback() } else { - if (is_streaming()) + if (is_streaming() && bf_aborted_in_total_order_ == false) { streaming_rollback(); } @@ -542,16 +543,16 @@ int wsrep::transaction::before_rollback() } break; case s_cert_failed: - if (is_streaming()) + if (is_streaming() && bf_aborted_in_total_order_ == false) { streaming_rollback(); } state(lock, s_aborting); break; case s_aborting: - if (is_streaming()) + if (is_streaming() && bf_aborted_in_total_order_ == false) { - provider().rollback(id_); + streaming_rollback(); } break; case s_must_replay: @@ -840,6 +841,18 @@ bool wsrep::transaction::bf_abort( return ret; } +bool wsrep::transaction::total_order_bf_abort( + wsrep::unique_lock& lock WSREP_UNUSED, + wsrep::seqno bf_seqno) +{ + bool ret(bf_abort(lock, bf_seqno)); + if (ret) + { + bf_aborted_in_total_order_ = true; + } + return ret; +} + //////////////////////////////////////////////////////////////////////////////// // Private // //////////////////////////////////////////////////////////////////////////////// @@ -1278,6 +1291,7 @@ void wsrep::transaction::cleanup() bf_abort_state_ = s_executing; bf_abort_provider_status_ = wsrep::provider::success; bf_abort_client_state_ = 0; + bf_aborted_in_total_order_ = false; ws_meta_ = wsrep::ws_meta(); flags_ = 0; certified_ = false;