mirror of
https://github.com/codership/wsrep-lib.git
synced 2025-04-18 10:24:01 +03:00
Add a method to disable BF aborts for transaction
This commit is contained in:
parent
7d108eb870
commit
06b07fe940
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2019 Codership Oy <info@codership.com>
|
||||
* Copyright (C) 2018-2024 Codership Oy <info@codership.com>
|
||||
*
|
||||
* This file is part of wsrep-lib.
|
||||
*
|
||||
@ -422,6 +422,7 @@ namespace wsrep
|
||||
int ordered_commit();
|
||||
|
||||
int after_commit();
|
||||
|
||||
/** @} */
|
||||
int before_rollback();
|
||||
|
||||
@ -562,6 +563,22 @@ namespace wsrep
|
||||
*/
|
||||
int total_order_bf_abort(wsrep::seqno bf_seqno);
|
||||
|
||||
/*
|
||||
* Disable BF aborts for an active transaction. This method
|
||||
* may be called several times during the transaction lifetime.
|
||||
* Calling before_prepare() or before_commit() after calling
|
||||
* this method will result error. The BF aborts are enabled again
|
||||
* in the next call to after_statement().
|
||||
*
|
||||
* BF aborts cannot be disabled in the following cases: 1) The
|
||||
* transactions has already been BF aborted. 2) The transaction
|
||||
* has generated a write set.
|
||||
*
|
||||
* @return Zero on success, non-zero if the transaction was found
|
||||
* BF aborted.
|
||||
*/
|
||||
int disable_bf_abort();
|
||||
|
||||
/**
|
||||
* Adopt a streaming transaction state. This is must be
|
||||
* called from high_priority_service::adopt_transaction()
|
||||
|
@ -202,6 +202,8 @@ namespace wsrep
|
||||
wsrep::seqno bf_seqno);
|
||||
bool total_order_bf_abort(wsrep::unique_lock<wsrep::mutex>&,
|
||||
wsrep::seqno bf_seqno);
|
||||
int disable_bf_abort();
|
||||
|
||||
|
||||
void clone_for_replay(const wsrep::transaction& other);
|
||||
|
||||
|
@ -538,6 +538,13 @@ int wsrep::client_state::total_order_bf_abort(wsrep::seqno bf_seqno)
|
||||
return total_order_bf_abort(lock, bf_seqno);
|
||||
}
|
||||
|
||||
int wsrep::client_state::disable_bf_abort()
|
||||
{
|
||||
assert(owning_thread_id_ == wsrep::this_thread::get_id());
|
||||
assert(state_ == s_exec || mode_ == m_local);
|
||||
return transaction_.disable_bf_abort();
|
||||
}
|
||||
|
||||
void wsrep::client_state::adopt_transaction(
|
||||
const wsrep::transaction& transaction)
|
||||
{
|
||||
|
@ -282,6 +282,11 @@ int wsrep::transaction::before_prepare(
|
||||
assert(state() == s_executing || state() == s_must_abort ||
|
||||
state() == s_replaying);
|
||||
|
||||
if (is_bf_immutable_) /* Was marked read-only */
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (state() == s_must_abort)
|
||||
{
|
||||
assert(client_state_.mode() == wsrep::client_state::m_local);
|
||||
@ -454,6 +459,11 @@ int wsrep::transaction::before_commit()
|
||||
assert((state() != s_committing && state() != s_replaying) ||
|
||||
certified());
|
||||
|
||||
if (is_bf_immutable_) /* Was marked read-only */
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (client_state_.mode())
|
||||
{
|
||||
case wsrep::client_state::m_local:
|
||||
@ -1117,6 +1127,24 @@ bool wsrep::transaction::total_order_bf_abort(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wsrep::transaction::disable_bf_abort()
|
||||
{
|
||||
wsrep::unique_lock<wsrep::mutex> lock{client_state_.mutex()};
|
||||
assert(active());
|
||||
assert(state() == s_executing || state() == s_must_abort);
|
||||
if (not is_empty())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (state() == s_must_abort)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
is_bf_immutable_ = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void wsrep::transaction::clone_for_replay(const wsrep::transaction& other)
|
||||
{
|
||||
assert(other.state() == s_replaying);
|
||||
|
@ -1267,6 +1267,49 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_keep_error_bf_after_after_command_b
|
||||
BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(transaction_disable_bf_abort,
|
||||
replicating_client_fixture_sync_rm)
|
||||
{
|
||||
cc.start_transaction(wsrep::transaction_id(1));
|
||||
BOOST_REQUIRE_EQUAL(cc.disable_bf_abort(), 0);
|
||||
|
||||
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing);
|
||||
BOOST_REQUIRE_EQUAL(cc.before_prepare(), 1);
|
||||
BOOST_REQUIRE_EQUAL(cc.before_commit(), 1);
|
||||
|
||||
cc.before_rollback();
|
||||
cc.after_rollback();
|
||||
cc.after_statement();
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(transaction_disable_bf_abort_bf_aborted,
|
||||
replicating_client_fixture_sync_rm)
|
||||
{
|
||||
cc.start_transaction(wsrep::transaction_id(1));
|
||||
wsrep_test::bf_abort_unordered(cc);
|
||||
BOOST_REQUIRE_EQUAL(cc.disable_bf_abort(), 1);
|
||||
cc.before_rollback();
|
||||
cc.after_rollback();
|
||||
cc.after_statement();
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(transaction_disable_bf_abort_key_appended,
|
||||
replicating_client_fixture_sync_rm)
|
||||
{
|
||||
cc.start_transaction(wsrep::transaction_id(1));
|
||||
int vals[3] = {1, 2, 3};
|
||||
wsrep::key key(wsrep::key::exclusive);
|
||||
for (int i(0); i < 3; ++i)
|
||||
{
|
||||
key.append_key_part(&vals[i], sizeof(vals[i]));
|
||||
}
|
||||
BOOST_REQUIRE_EQUAL(cc.append_key(key), 0);
|
||||
BOOST_REQUIRE_EQUAL(cc.disable_bf_abort(), 1);
|
||||
cc.before_rollback();
|
||||
cc.after_rollback();
|
||||
cc.after_statement();
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(transaction_1pc_applying,
|
||||
applying_client_fixture)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user