1
0
mirror of https://github.com/codership/wsrep-lib.git synced 2025-07-31 18:24:25 +03:00

Track commit states for read-only transactions

Read-only transactions which don't produce any changes were
not tracker properly. Added tracking for read-only transaction
commit states. One phase commit is assumed.
This commit is contained in:
Teemu Ollakka
2023-04-04 09:36:17 +03:00
parent 3115584c66
commit 12c8069f09
3 changed files with 60 additions and 2 deletions

View File

@ -238,6 +238,8 @@ namespace wsrep
wsrep::provider& provider(); wsrep::provider& provider();
void flags(int flags) { flags_ = flags; } void flags(int flags) { flags_ = flags; }
bool is_read_only() const;
int before_commit_local_read_only(wsrep::unique_lock<wsrep::mutex>&);
int before_commit_local(wsrep::unique_lock<wsrep::mutex>&); int before_commit_local(wsrep::unique_lock<wsrep::mutex>&);
int before_commit_high_priority(wsrep::unique_lock<wsrep::mutex>&); int before_commit_high_priority(wsrep::unique_lock<wsrep::mutex>&);
// Return true if the transaction must abort, is aborting, // Return true if the transaction must abort, is aborting,

View File

@ -438,15 +438,42 @@ int wsrep::transaction::after_prepare(
return ret; return ret;
} }
bool wsrep::transaction::is_read_only() const
{
return sr_keys_.empty();
}
int wsrep::transaction::before_commit_local_read_only(
wsrep::unique_lock<wsrep::mutex>& lock)
{
assert(lock.owns_lock());
assert(state() == s_executing || state() == s_must_abort);
if (state() == s_must_abort)
{
state(lock, s_aborting);
return 1;
}
state(lock, s_preparing);
state(lock, s_committing);
return 0;
}
int wsrep::transaction::before_commit_local( int wsrep::transaction::before_commit_local(
wsrep::unique_lock<wsrep::mutex>& lock) wsrep::unique_lock<wsrep::mutex>& lock)
{ {
int ret = 1; assert(lock.owns_lock());
if (is_read_only()) {
return before_commit_local_read_only(lock);
}
assert(state() == s_executing || state() == s_prepared assert(state() == s_executing || state() == s_prepared
|| state() == s_committing || state() == s_must_abort || state() == s_committing || state() == s_must_abort
|| state() == s_replaying); || state() == s_replaying);
assert((state() != s_committing && state() != s_replaying) || certified()); assert((state() != s_committing && state() != s_replaying) || certified());
int ret = 1;
if (state() == s_executing) if (state() == s_executing)
{ {
ret = before_prepare(lock) || after_prepare(lock); ret = before_prepare(lock) || after_prepare(lock);
@ -512,6 +539,7 @@ int wsrep::transaction::before_commit_local(
int wsrep::transaction::before_commit_high_priority( int wsrep::transaction::before_commit_high_priority(
wsrep::unique_lock<wsrep::mutex>& lock) wsrep::unique_lock<wsrep::mutex>& lock)
{ {
assert(lock.owns_lock());
int ret = 1; int ret = 1;
assert(certified()); assert(certified());
assert(ordered()); assert(ordered());
@ -568,6 +596,14 @@ int wsrep::transaction::ordered_commit()
wsrep::unique_lock<wsrep::mutex> lock(client_state_.mutex()); wsrep::unique_lock<wsrep::mutex> lock(client_state_.mutex());
debug_log_state("ordered_commit_enter"); debug_log_state("ordered_commit_enter");
assert(state() == s_committing); assert(state() == s_committing);
if (is_read_only())
{
state(lock, s_ordered_commit);
debug_log_state("ordered_commit_leave read_only");
return 0;
}
assert(ordered()); assert(ordered());
client_service_.debug_sync("wsrep_before_commit_order_leave"); client_service_.debug_sync("wsrep_before_commit_order_leave");
int ret(provider().commit_order_leave(ws_handle_, ws_meta_, int ret(provider().commit_order_leave(ws_handle_, ws_meta_,

View File

@ -1294,8 +1294,28 @@ BOOST_FIXTURE_TEST_CASE(transaction_read_only,
cc.start_transaction(wsrep::transaction_id(1)); cc.start_transaction(wsrep::transaction_id(1));
BOOST_REQUIRE(cc.before_commit() == 0); BOOST_REQUIRE(cc.before_commit() == 0);
BOOST_REQUIRE(sc.provider().commit_fragments() == 0); BOOST_REQUIRE(sc.provider().commit_fragments() == 0);
BOOST_REQUIRE(cc.ordered_commit() == 0);
BOOST_REQUIRE(cc.after_commit() == 0);
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committed);
BOOST_REQUIRE(cc.after_statement() == 0);
} }
BOOST_FIXTURE_TEST_CASE(transaction_bf_abort_read_only,
replicating_client_fixture_sync_rm)
{
cc.start_transaction(wsrep::transaction_id(1));
wsrep_test::bf_abort_unordered(cc);
BOOST_REQUIRE(cc.before_commit() == 1);
BOOST_REQUIRE(sc.provider().commit_fragments() == 0);
BOOST_REQUIRE(cc.before_rollback() == 0);
BOOST_REQUIRE(cc.after_rollback() == 0);
BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted);
BOOST_REQUIRE(cc.after_statement() == 1);
BOOST_REQUIRE(cc.current_error() == wsrep::client_error::e_deadlock_error);
}
BOOST_FIXTURE_TEST_CASE(transaction_1pc_applying, BOOST_FIXTURE_TEST_CASE(transaction_1pc_applying,
applying_client_fixture) applying_client_fixture)
{ {