mirror of
https://github.com/codership/wsrep-lib.git
synced 2025-07-28 20:02:00 +03:00
added new transaction state: s_waiting_for_replayers
to make it posisble to diagnose from outside, if potential BF victim transaction is blocked in replayer wait loop (before entering commit phase). Also, added new forced state change to s_must_abort, if before_rollback() is used for a transaction in s_committing state. Such situation can happen, if BF abort happens for a victim, which has passed certification and moved to commit phase before the BF aborting happens.
This commit is contained in:
@ -58,6 +58,7 @@ namespace wsrep
|
||||
s_aborting,
|
||||
s_aborted,
|
||||
s_must_replay,
|
||||
s_waiting_for_replayers,
|
||||
s_replaying
|
||||
};
|
||||
static const int n_states = s_replaying + 1;
|
||||
@ -299,6 +300,7 @@ namespace wsrep
|
||||
case wsrep::transaction::s_aborting: return "aborting";
|
||||
case wsrep::transaction::s_aborted: return "aborted";
|
||||
case wsrep::transaction::s_must_replay: return "must_replay";
|
||||
case wsrep::transaction::s_waiting_for_replayers: return "waiting_for_replayers";
|
||||
case wsrep::transaction::s_replaying: return "replaying";
|
||||
}
|
||||
return "unknown";
|
||||
|
@ -660,6 +660,7 @@ int wsrep::transaction::before_rollback()
|
||||
state() == s_preparing ||
|
||||
state() == s_prepared ||
|
||||
state() == s_must_abort ||
|
||||
state() == s_committing ||
|
||||
// Background rollbacker or rollback initiated from SE
|
||||
state() == s_aborting ||
|
||||
state() == s_cert_failed ||
|
||||
@ -672,6 +673,15 @@ int wsrep::transaction::before_rollback()
|
||||
{
|
||||
client_service_.debug_sync("wsrep_before_SR_rollback");
|
||||
}
|
||||
/* this state change was added to support BF aborting
|
||||
at later state (before prepare), where victim has certified
|
||||
successfully, and state has already
|
||||
propagated to committing phase
|
||||
*/
|
||||
if (state() == s_committing) {
|
||||
state(lock, s_must_abort);
|
||||
}
|
||||
|
||||
switch (state())
|
||||
{
|
||||
case s_preparing:
|
||||
@ -984,6 +994,7 @@ bool wsrep::transaction::bf_abort(
|
||||
case s_preparing:
|
||||
case s_prepared:
|
||||
case s_certifying:
|
||||
case s_waiting_for_replayers:
|
||||
case s_committing:
|
||||
{
|
||||
wsrep::seqno victim_seqno;
|
||||
@ -1306,22 +1317,22 @@ void wsrep::transaction::state(
|
||||
next_state == s_aborting);
|
||||
|
||||
static const char allowed[n_states][n_states] =
|
||||
{ /* ex pg pd ce co oc ct cf ma ab ad mr re */
|
||||
{ 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0}, /* ex */
|
||||
{ 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0}, /* pg */
|
||||
{ 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0}, /* pd */
|
||||
{ 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0}, /* ce */
|
||||
{ 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0}, /* co */
|
||||
{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, /* oc */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* ct */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}, /* cf */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0}, /* ma */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, /* ab */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* ad */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* mr */
|
||||
{ 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0} /* re */
|
||||
{ /* ex pg pd ce co oc ct cf ma ab ad mr wr re */
|
||||
{ 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0}, /* ex */
|
||||
{ 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0}, /* pg */
|
||||
{ 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0}, /* pd */
|
||||
{ 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0}, /* ce */
|
||||
{ 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0}, /* co */
|
||||
{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, /* oc */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* ct */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, /* cf */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0}, /* ma */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}, /* ab */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* ad */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* mr */
|
||||
{ 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1}, /* wr */
|
||||
{ 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0} /* re */
|
||||
};
|
||||
|
||||
if (!allowed[state_][next_state])
|
||||
{
|
||||
wsrep::log_debug() << "unallowed state transition for transaction "
|
||||
@ -1681,6 +1692,7 @@ int wsrep::transaction::certify_commit(
|
||||
{
|
||||
assert(lock.owns_lock());
|
||||
assert(active());
|
||||
state(lock, s_waiting_for_replayers);
|
||||
client_service_.wait_for_replayers(lock);
|
||||
|
||||
assert(lock.owns_lock());
|
||||
|
Reference in New Issue
Block a user