1
0
mirror of https://github.com/codership/wsrep-lib.git synced 2025-04-19 21:02:17 +03:00

Add a method to disable BF aborts for transaction

This commit is contained in:
Teemu Ollakka 2024-03-20 19:05:36 +02:00
parent 7d108eb870
commit 06b07fe940
5 changed files with 98 additions and 1 deletions

View File

@ -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()

View File

@ -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);

View File

@ -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)
{

View File

@ -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);

View File

@ -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)
{