1
0
mirror of https://github.com/codership/wsrep-lib.git synced 2025-04-27 18:56:49 +03:00

* Fixed wrong error code returned from client_context::before_command

* Fixed raw depends_on assignment from native to wsrep::seqno
* More debug logging
This commit is contained in:
Teemu Ollakka 2018-06-12 13:17:01 +03:00
parent 3456a8b953
commit d9d41a4787
6 changed files with 85 additions and 40 deletions

View File

@ -392,7 +392,7 @@ namespace wsrep
friend class client_toi_mode; friend class client_toi_mode;
friend class transaction_context; friend class transaction_context;
void debug_log_state(const char*) const;
/*! /*!
* Set client state. * Set client state.
*/ */

View File

@ -4,6 +4,7 @@
#include "wsrep/client_context.hpp" #include "wsrep/client_context.hpp"
#include "wsrep/compiler.hpp" #include "wsrep/compiler.hpp"
#include "wsrep/logger.hpp"
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
@ -29,6 +30,7 @@ void wsrep::client_context::override_error(enum wsrep::client_error error)
int wsrep::client_context::before_command() int wsrep::client_context::before_command()
{ {
wsrep::unique_lock<wsrep::mutex> lock(mutex_); wsrep::unique_lock<wsrep::mutex> lock(mutex_);
debug_log_state("before_command: enter");
assert(state_ == s_idle); assert(state_ == s_idle);
if (server_context_.rollback_mode() == wsrep::server_context::rm_sync) if (server_context_.rollback_mode() == wsrep::server_context::rm_sync)
{ {
@ -63,6 +65,8 @@ int wsrep::client_context::before_command()
wsrep::transaction_context::s_aborted); wsrep::transaction_context::s_aborted);
assert(transaction_.active() == false); assert(transaction_.active() == false);
assert(current_error() != wsrep::e_success); assert(current_error() != wsrep::e_success);
debug_log_state("before_command: error");
return 1;
} }
else if (transaction_.state() == wsrep::transaction_context::s_aborted) else if (transaction_.state() == wsrep::transaction_context::s_aborted)
{ {
@ -74,15 +78,18 @@ int wsrep::client_context::before_command()
(void)transaction_.after_statement(); (void)transaction_.after_statement();
lock.lock(); lock.lock();
assert(transaction_.active() == false); assert(transaction_.active() == false);
} debug_log_state("before_command: error");
return 1; return 1;
} }
}
debug_log_state("before_command: success");
return 0; return 0;
} }
void wsrep::client_context::after_command_before_result() void wsrep::client_context::after_command_before_result()
{ {
wsrep::unique_lock<wsrep::mutex> lock(mutex_); wsrep::unique_lock<wsrep::mutex> lock(mutex_);
debug_log_state("after_command_before_result: enter");
assert(state() == s_exec); assert(state() == s_exec);
if (transaction_.active() && if (transaction_.active() &&
transaction_.state() == wsrep::transaction_context::s_must_abort) transaction_.state() == wsrep::transaction_context::s_must_abort)
@ -96,11 +103,13 @@ void wsrep::client_context::after_command_before_result()
assert(current_error() != wsrep::e_success); assert(current_error() != wsrep::e_success);
} }
state(lock, s_result); state(lock, s_result);
debug_log_state("after_command_before_result: leave");
} }
void wsrep::client_context::after_command_after_result() void wsrep::client_context::after_command_after_result()
{ {
wsrep::unique_lock<wsrep::mutex> lock(mutex_); wsrep::unique_lock<wsrep::mutex> lock(mutex_);
debug_log_state("after_command_after_result_enter");
assert(state() == s_result); assert(state() == s_result);
assert(transaction_.state() != wsrep::transaction_context::s_aborting); assert(transaction_.state() != wsrep::transaction_context::s_aborting);
if (transaction_.active() && if (transaction_.active() &&
@ -117,11 +126,13 @@ void wsrep::client_context::after_command_after_result()
current_error_ = wsrep::e_success; current_error_ = wsrep::e_success;
} }
state(lock, s_idle); state(lock, s_idle);
debug_log_state("after_command_after_result: leave");
} }
int wsrep::client_context::before_statement() int wsrep::client_context::before_statement()
{ {
wsrep::unique_lock<wsrep::mutex> lock(mutex_); wsrep::unique_lock<wsrep::mutex> lock(mutex_);
debug_log_state("before_statement: enter");
#if 0 #if 0
/*! /*!
* \todo It might be beneficial to implement timed wait for * \todo It might be beneficial to implement timed wait for
@ -138,8 +149,10 @@ int wsrep::client_context::before_statement()
transaction_.state() == wsrep::transaction_context::s_must_abort) transaction_.state() == wsrep::transaction_context::s_must_abort)
{ {
// Rollback and cleanup will happen in after_command_before_result() // Rollback and cleanup will happen in after_command_before_result()
debug_log_state("before_statement_error");
return 1; return 1;
} }
debug_log_state("before_statement: success");
return 0; return 0;
} }
@ -147,6 +160,7 @@ enum wsrep::client_context::after_statement_result
wsrep::client_context::after_statement() wsrep::client_context::after_statement()
{ {
// wsrep::unique_lock<wsrep::mutex> lock(mutex_); // wsrep::unique_lock<wsrep::mutex> lock(mutex_);
debug_log_state("after_statement: enter");
assert(state() == s_exec); assert(state() == s_exec);
#if 0 #if 0
/*! /*!
@ -158,18 +172,32 @@ wsrep::client_context::after_statement()
{ {
if (is_autocommit()) if (is_autocommit())
{ {
debug_log_state("after_statement: may_retry");
return asr_may_retry; return asr_may_retry;
} }
else else
{ {
debug_log_state("after_statement: error");
return asr_error; return asr_error;
} }
} }
debug_log_state("after_statement: success");
return asr_success; return asr_success;
} }
// Private // Private
void wsrep::client_context::debug_log_state(const char* context) const
{
if (debug_log_level() >= 1)
{
wsrep::log_debug() << "client_context: " << context
<< ": server: " << server_context_.name()
<< " client: " << id_.get()
<< " current_error: " << current_error_;
}
}
void wsrep::client_context::state( void wsrep::client_context::state(
wsrep::unique_lock<wsrep::mutex>& lock WSREP_UNUSED, wsrep::unique_lock<wsrep::mutex>& lock WSREP_UNUSED,
enum wsrep::client_context::state state) enum wsrep::client_context::state state)

View File

@ -78,6 +78,7 @@ public:
void start(wsrep::client_context* cc) void start(wsrep::client_context* cc)
{ {
// wsrep::log_debug() << "Start: " << cc;
wsrep::unique_lock<wsrep::mutex> lock(se_.mutex_); wsrep::unique_lock<wsrep::mutex> lock(se_.mutex_);
if (se_.transactions_.insert(cc).second == false) if (se_.transactions_.insert(cc).second == false)
{ {
@ -88,6 +89,7 @@ public:
void commit() void commit()
{ {
// wsrep::log_debug() << "Commit: " << cc_;
if (cc_) if (cc_)
{ {
wsrep::unique_lock<wsrep::mutex> lock(se_.mutex_); wsrep::unique_lock<wsrep::mutex> lock(se_.mutex_);
@ -99,6 +101,7 @@ public:
void abort() void abort()
{ {
// wsrep::log_debug() << "Abort: " << cc_;
if (cc_) if (cc_)
{ {
wsrep::unique_lock<wsrep::mutex> lock(se_.mutex_); wsrep::unique_lock<wsrep::mutex> lock(se_.mutex_);
@ -133,7 +136,7 @@ public:
lock.unlock(); lock.unlock();
if (victim_txc->bf_abort(victim_txc_lock, txc.seqno())) if (victim_txc->bf_abort(victim_txc_lock, txc.seqno()))
{ {
wsrep::log() << "BF aborted " << victim_txc->id().get(); // wsrep::log() << "BF aborted " << victim_txc->id().get();
++bf_aborts_; ++bf_aborts_;
} }
} }
@ -359,9 +362,9 @@ private:
} }
int rollback() override int rollback() override
{ {
wsrep::log() << "rollback: " << transaction().id().get() // wsrep::log() << "rollback: " << transaction().id().get()
<< "state: " // << "state: "
<< wsrep::to_string(transaction().state()); // << wsrep::to_string(transaction().state());
before_rollback(); before_rollback();
se_trx_.abort(); se_trx_.abort();
after_rollback(); after_rollback();
@ -371,7 +374,7 @@ private:
void will_replay(wsrep::transaction_context&) override { } void will_replay(wsrep::transaction_context&) override { }
int replay(wsrep::transaction_context& txc) override int replay(wsrep::transaction_context& txc) override
{ {
wsrep::log() << "replay: " << txc.id().get(); // wsrep::log() << "replay: " << txc.id().get();
wsrep::client_applier_mode applier_mode(*this); wsrep::client_applier_mode applier_mode(*this);
++stats_.replays; ++stats_.replays;
return provider().replay(txc.ws_handle(), this); return provider().replay(txc.ws_handle(), this);
@ -400,6 +403,7 @@ private:
int client_command(Func f) int client_command(Func f)
{ {
int err(before_command()); int err(before_command());
// wsrep::log_debug() << "before_command: " << err;
// If err != 0, transaction was BF aborted while client idle // If err != 0, transaction was BF aborted while client idle
if (err == 0) if (err == 0)
{ {
@ -413,11 +417,13 @@ private:
after_command_before_result(); after_command_before_result();
if (current_error()) if (current_error())
{ {
// wsrep::log_info() << "Current error";
assert(transaction_.state() == assert(transaction_.state() ==
wsrep::transaction_context::s_aborted); wsrep::transaction_context::s_aborted);
err = 1; err = 1;
} }
after_command_after_result(); after_command_after_result();
// wsrep::log_info() << "client_command(): " << err;
return err; return err;
} }
@ -427,6 +433,7 @@ private:
int err = client_command( int err = client_command(
[&]() [&]()
{ {
// wsrep::log_debug() << "Start transaction";
err = start_transaction(server_.next_transaction_id()); err = start_transaction(server_.next_transaction_id());
assert(err == 0); assert(err == 0);
se_trx_.start(this); se_trx_.start(this);
@ -435,6 +442,7 @@ private:
err = err || client_command( err = err || client_command(
[&]() [&]()
{ {
// wsrep::log_debug() << "Generate write set";
assert(transaction().active()); assert(transaction().active());
assert(err == 0); assert(err == 0);
int data(std::rand() % 10000000); int data(std::rand() % 10000000);
@ -453,6 +461,7 @@ private:
err = err || client_command( err = err || client_command(
[&]() [&]()
{ {
// wsrep::log_debug() << "Commit";
assert(err == 0); assert(err == 0);
if (do_2pc()) if (do_2pc())
{ {

View File

@ -13,6 +13,13 @@
#include <sstream> #include <sstream>
#include <memory> #include <memory>
#define WSREP_TC_LOG_DEBUG(level, msg) \
do { \
if (client_context_.debug_log_level() < level) \
{ } \
else wsrep::log_debug() << msg; \
} while (0)
// Public // Public
wsrep::transaction_context::transaction_context( wsrep::transaction_context::transaction_context(
@ -489,12 +496,13 @@ bool wsrep::transaction_context::bf_abort(
if (active() == false) if (active() == false)
{ {
wsrep::log() << "Transaction not active, skipping bf abort"; WSREP_TC_LOG_DEBUG(1, "Transaction not active, skipping bf abort");
} }
else if (ordered() && seqno() < bf_seqno) else if (ordered() && seqno() < bf_seqno)
{ {
wsrep::log() << "Not allowed to BF abort transaction ordered before " WSREP_TC_LOG_DEBUG(1,
<< "aborter: " << seqno() << " < " << bf_seqno; "Not allowed to BF abort transaction ordered before "
<< "aborter: " << seqno() << " < " << bf_seqno);
} }
else else
{ {
@ -512,31 +520,26 @@ bool wsrep::transaction_context::bf_abort(
switch (status) switch (status)
{ {
case wsrep::provider::success: case wsrep::provider::success:
if (client_context_.debug_log_level() >= 1) WSREP_TC_LOG_DEBUG(1, "Seqno " << bf_seqno
{
wsrep::log_debug() << "Seqno " << bf_seqno
<< " succesfully BF aborted " << id_.get() << " succesfully BF aborted " << id_.get()
<< " victim_seqno " << victim_seqno; << " victim_seqno " << victim_seqno);
}
bf_abort_state_ = state(); bf_abort_state_ = state();
state(lock, s_must_abort); state(lock, s_must_abort);
ret = true; ret = true;
break; break;
default: default:
if (client_context_.debug_log_level() >= 1) WSREP_TC_LOG_DEBUG(1,
{ "Seqno " << bf_seqno
wsrep::log_debug() << "Seqno " << bf_seqno
<< " failed to BF abort " << id_.get() << " failed to BF abort " << id_.get()
<< " with status " << status << " with status " << status
<< " victim_seqno " << victim_seqno; << " victim_seqno " << victim_seqno);
}
break; break;
} }
break; break;
} }
default: default:
wsrep::log() << "BF abort not allowed in state " WSREP_TC_LOG_DEBUG(1, "BF abort not allowed in state "
<< wsrep::to_string(state()); << wsrep::to_string(state()));
break; break;
} }
} }
@ -604,7 +607,7 @@ void wsrep::transaction_context::state(
os << "unallowed state transition for transaction " os << "unallowed state transition for transaction "
<< id_.get() << ": " << wsrep::to_string(state_) << id_.get() << ": " << wsrep::to_string(state_)
<< " -> " << wsrep::to_string(next_state); << " -> " << wsrep::to_string(next_state);
wsrep::log() << os.str(); wsrep::log_error() << os.str();
throw wsrep::runtime_error(os.str()); throw wsrep::runtime_error(os.str());
} }
} }
@ -854,14 +857,12 @@ void wsrep::transaction_context::cleanup()
void wsrep::transaction_context::debug_log_state( void wsrep::transaction_context::debug_log_state(
const char* context) const const char* context) const
{ {
if (client_context_.debug_log_level() >= 1) WSREP_TC_LOG_DEBUG(
{ 1, context
wsrep::log_debug() << context
<< ": server: " << client_context_.server_context().name() << ": server: " << client_context_.server_context().name()
<< ": client: " << client_context_.id().get() << " client: " << client_context_.id().get()
<< " trx: " << int64_t(id_.get()) << " trx: " << int64_t(id_.get())
<< " state: " << wsrep::to_string(state_) << " state: " << wsrep::to_string(state_)
<< " error: " << " error: "
<< wsrep::to_string(client_context_.current_error()); << wsrep::to_string(client_context_.current_error()));
}
} }

View File

@ -141,6 +141,13 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(transaction_context_1pc, T,
BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1)); BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1));
BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_executing); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_executing);
// Verify that the commit can be succesfully executed in separate command
BOOST_REQUIRE(cc.after_statement() == wsrep::client_context::asr_success);
cc.after_command_before_result();
cc.after_command_after_result();
BOOST_REQUIRE(cc.current_error() == wsrep::e_success);
BOOST_REQUIRE(cc.before_command() == 0);
BOOST_REQUIRE(cc.before_statement() == 0);
// Run before commit // Run before commit
BOOST_REQUIRE(cc.before_commit() == 0); BOOST_REQUIRE(cc.before_commit() == 0);
BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_committing); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_committing);
@ -940,7 +947,7 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(
cc.after_statement(); cc.after_statement();
cc.after_command_before_result(); cc.after_command_before_result();
cc.after_command_after_result(); cc.after_command_after_result();
cc.before_command(); BOOST_REQUIRE(cc.before_command() == 0);
BOOST_REQUIRE(tc.active()); BOOST_REQUIRE(tc.active());
BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_executing); BOOST_REQUIRE(tc.state() == wsrep::transaction_context::s_executing);
wsrep_test::bf_abort_unordered(cc); wsrep_test::bf_abort_unordered(cc);

View File

@ -323,7 +323,7 @@ namespace
wsrep::stid(wsrep::id(meta->stid.node.data, wsrep::stid(wsrep::id(meta->stid.node.data,
sizeof(meta->stid.node.data)), sizeof(meta->stid.node.data)),
meta->stid.trx, meta->stid.trx,
meta->stid.conn), wsrep::seqno(meta->depends_on), meta->stid.conn), wsrep::seqno(seqno_from_native(meta->depends_on)),
map_flags_from_native(flags)); map_flags_from_native(flags));
if (ret == WSREP_CB_SUCCESS && if (ret == WSREP_CB_SUCCESS &&
client_context->server_context().on_apply( client_context->server_context().on_apply(