1
0
mirror of https://github.com/codership/wsrep-lib.git synced 2025-07-30 07:23:07 +03:00

Ensure that client_service::will_replay() is called.

Modified tests to verify that client_service::will_replay() is
called whenever it is determined that the transaction must replay.

Added a test to verify behavior when provider::commit_order_enter()
returns BF abort error.

Moved call to client_service::will_replay() into transaction::state()
to ensure that it is always called when shift to s_must_replay
happens.
This commit is contained in:
Teemu Ollakka
2020-10-19 06:12:17 +03:00
parent ec767cd3f0
commit d1482feb32
4 changed files with 61 additions and 5 deletions

View File

@ -1142,6 +1142,11 @@ void wsrep::transaction::state(
state_hist_.erase(state_hist_.begin()); state_hist_.erase(state_hist_.begin());
} }
state_ = next_state; state_ = next_state;
if (state_ == s_must_replay)
{
client_service_.will_replay();
}
} }
bool wsrep::transaction::abort_or_interrupt( bool wsrep::transaction::abort_or_interrupt(
@ -1531,7 +1536,6 @@ int wsrep::transaction::certify_commit(
// We got BF aborted after succesful certification // We got BF aborted after succesful certification
// and before acquiring client state lock. The trasaction // and before acquiring client state lock. The trasaction
// must be replayed. // must be replayed.
client_service_.will_replay();
state(lock, s_must_replay); state(lock, s_must_replay);
break; break;
default: default:
@ -1557,7 +1561,6 @@ int wsrep::transaction::certify_commit(
// yet known. Therefore the transaction must roll back // yet known. Therefore the transaction must roll back
// and go through replay either to replay and commit the whole // and go through replay either to replay and commit the whole
// transaction or to determine failed certification status. // transaction or to determine failed certification status.
client_service_.will_replay();
if (state() != s_must_abort) if (state() != s_must_abort)
{ {
state(lock, s_must_abort); state(lock, s_must_abort);

View File

@ -72,6 +72,7 @@ namespace wsrep
, sync_point_action_() , sync_point_action_()
, bytes_generated_() , bytes_generated_()
, client_state_(client_state) , client_state_(client_state)
, will_replay_called_()
, replays_() , replays_()
, aborts_() , aborts_()
{ } { }
@ -98,10 +99,11 @@ namespace wsrep
return 0; return 0;
} }
} }
void will_replay() WSREP_OVERRIDE { }
enum wsrep::provider::status void will_replay() WSREP_OVERRIDE { will_replay_called_ = true; }
replay() WSREP_OVERRIDE;
enum wsrep::provider::status replay() WSREP_OVERRIDE;
void wait_for_replayers( void wait_for_replayers(
wsrep::unique_lock<wsrep::mutex>& lock) wsrep::unique_lock<wsrep::mutex>& lock)
WSREP_OVERRIDE WSREP_OVERRIDE
@ -195,10 +197,12 @@ namespace wsrep
// //
// Verifying the state // Verifying the state
// //
bool will_replay_called() const { return will_replay_called_; }
size_t replays() const { return replays_; } size_t replays() const { return replays_; }
size_t aborts() const { return aborts_; } size_t aborts() const { return aborts_; }
private: private:
wsrep::mock_client_state& client_state_; wsrep::mock_client_state& client_state_;
bool will_replay_called_;
size_t replays_; size_t replays_;
size_t aborts_; size_t aborts_;
}; };

View File

@ -249,6 +249,46 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(
BOOST_REQUIRE(cc.current_error()); BOOST_REQUIRE(cc.current_error());
} }
BOOST_FIXTURE_TEST_CASE_TEMPLATE(
transaction_1pc_bf_during_commit_order_enter, T,
replicating_fixtures, T)
{
wsrep::mock_client& cc(T::cc);
const wsrep::transaction& tc(T::tc);
auto& sc(T::sc);
// Start a new transaction with ID 1
cc.start_transaction(wsrep::transaction_id(1));
BOOST_REQUIRE(tc.active());
BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
sc.provider().commit_order_enter_result_ = wsrep::provider::error_bf_abort;
// Run before commit
BOOST_REQUIRE(cc.before_commit());
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
BOOST_REQUIRE(cc.will_replay_called() == true);
BOOST_REQUIRE(tc.certified() == true);
BOOST_REQUIRE(tc.ordered() == true);
sc.provider().commit_order_enter_result_ = wsrep::provider::success;
// Rollback sequence
BOOST_REQUIRE(cc.before_rollback() == 0);
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
BOOST_REQUIRE(cc.after_rollback() == 0);
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
// Replay from after_statement()
cc.after_statement();
BOOST_REQUIRE(cc.replays() > 0);
BOOST_REQUIRE(tc.active() == false);
BOOST_REQUIRE(tc.ordered() == false);
BOOST_REQUIRE(tc.certified() == false);
BOOST_REQUIRE(not cc.current_error());
}
// //
// Test a 1PC transaction for which prepare data fails // Test a 1PC transaction for which prepare data fails
// //
@ -341,6 +381,7 @@ BOOST_FIXTURE_TEST_CASE(
BOOST_REQUIRE(cc.before_commit()); BOOST_REQUIRE(cc.before_commit());
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
BOOST_REQUIRE(cc.will_replay_called() == true);
BOOST_REQUIRE(cc.after_statement() == 0); BOOST_REQUIRE(cc.after_statement() == 0);
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committed); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committed);
BOOST_REQUIRE(cc.current_error() == wsrep::e_success); BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
@ -361,6 +402,7 @@ BOOST_FIXTURE_TEST_CASE(
BOOST_REQUIRE(cc.before_commit()); BOOST_REQUIRE(cc.before_commit());
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
BOOST_REQUIRE(cc.will_replay_called() == true);
BOOST_REQUIRE(cc.after_statement() ); BOOST_REQUIRE(cc.after_statement() );
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error); BOOST_REQUIRE(cc.current_error() == wsrep::e_deadlock_error);
@ -391,6 +433,7 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(
// Run before commit // Run before commit
BOOST_REQUIRE(cc.before_commit()); BOOST_REQUIRE(cc.before_commit());
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
BOOST_REQUIRE(cc.will_replay_called() == true);
BOOST_REQUIRE(tc.certified() == false); BOOST_REQUIRE(tc.certified() == false);
BOOST_REQUIRE(tc.ordered() == true); BOOST_REQUIRE(tc.ordered() == true);
@ -755,6 +798,7 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(
// Run before commit // Run before commit
BOOST_REQUIRE(cc.before_commit()); BOOST_REQUIRE(cc.before_commit());
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
BOOST_REQUIRE(cc.will_replay_called() == true);
BOOST_REQUIRE(tc.certified() == true); BOOST_REQUIRE(tc.certified() == true);
BOOST_REQUIRE(tc.ordered() == true); BOOST_REQUIRE(tc.ordered() == true);
@ -1268,6 +1312,7 @@ BOOST_FIXTURE_TEST_CASE(transaction_row_streaming_bf_abort_committing,
BOOST_REQUIRE(cc.before_rollback() == 0); BOOST_REQUIRE(cc.before_rollback() == 0);
BOOST_REQUIRE(cc.after_rollback() == 0); BOOST_REQUIRE(cc.after_rollback() == 0);
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
BOOST_REQUIRE(cc.will_replay_called() == true);
BOOST_REQUIRE(cc.after_statement() == 0); BOOST_REQUIRE(cc.after_statement() == 0);
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committed); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committed);
BOOST_REQUIRE(sc.provider().fragments() == 2); BOOST_REQUIRE(sc.provider().fragments() == 2);

View File

@ -94,6 +94,7 @@ BOOST_FIXTURE_TEST_CASE(
wsrep_test::bf_abort_ordered(cc); wsrep_test::bf_abort_ordered(cc);
BOOST_REQUIRE(cc.after_prepare()); BOOST_REQUIRE(cc.after_prepare());
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
BOOST_REQUIRE(cc.will_replay_called() == true);
BOOST_REQUIRE(cc.before_rollback() == 0); BOOST_REQUIRE(cc.before_rollback() == 0);
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
BOOST_REQUIRE(cc.after_rollback() == 0); BOOST_REQUIRE(cc.after_rollback() == 0);
@ -124,6 +125,7 @@ BOOST_FIXTURE_TEST_CASE(
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
BOOST_REQUIRE(cc.before_rollback() == 0); BOOST_REQUIRE(cc.before_rollback() == 0);
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
BOOST_REQUIRE(cc.will_replay_called() == true);
BOOST_REQUIRE(cc.after_rollback() == 0); BOOST_REQUIRE(cc.after_rollback() == 0);
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
BOOST_REQUIRE(cc.after_statement() == 0); BOOST_REQUIRE(cc.after_statement() == 0);
@ -152,6 +154,7 @@ BOOST_FIXTURE_TEST_CASE(
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort);
BOOST_REQUIRE(cc.before_commit()); BOOST_REQUIRE(cc.before_commit());
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
BOOST_REQUIRE(cc.will_replay_called() == true);
BOOST_REQUIRE(tc.certified() == true); BOOST_REQUIRE(tc.certified() == true);
BOOST_REQUIRE(tc.ordered() == true); BOOST_REQUIRE(tc.ordered() == true);
BOOST_REQUIRE(cc.before_rollback() == 0); BOOST_REQUIRE(cc.before_rollback() == 0);
@ -183,6 +186,7 @@ BOOST_FIXTURE_TEST_CASE(
sc.provider().commit_order_enter_result_ = wsrep::provider::error_bf_abort; sc.provider().commit_order_enter_result_ = wsrep::provider::error_bf_abort;
BOOST_REQUIRE(cc.before_commit()); BOOST_REQUIRE(cc.before_commit());
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay);
BOOST_REQUIRE(cc.will_replay_called() == true);
BOOST_REQUIRE(tc.certified() == true); BOOST_REQUIRE(tc.certified() == true);
BOOST_REQUIRE(tc.ordered() == true); BOOST_REQUIRE(tc.ordered() == true);
sc.provider().commit_order_enter_result_ = wsrep::provider::success; sc.provider().commit_order_enter_result_ = wsrep::provider::success;