From fccdad6ee90def2615d97cc6619560ea90eddbc9 Mon Sep 17 00:00:00 2001 From: Teemu Ollakka Date: Tue, 8 Jan 2019 17:02:32 +0200 Subject: [PATCH] Changed certification to happen in before_prepare() Certification for commit fragments was changed to happen in before_prepare in order to make GTID available for storage engines in prepare phase. Removed unused file src/wsrep-lib_test.cpp --- src/transaction.cpp | 58 +++++++++++++++++++---------------- src/wsrep-lib_test.cpp | 22 ------------- test/transaction_test_2pc.cpp | 19 +++++++----- 3 files changed, 42 insertions(+), 57 deletions(-) delete mode 100644 src/wsrep-lib_test.cpp diff --git a/src/transaction.cpp b/src/transaction.cpp index a1eb051..b458924 100644 --- a/src/transaction.cpp +++ b/src/transaction.cpp @@ -266,8 +266,6 @@ int wsrep::transaction::before_prepare( return 1; } - state(lock, s_preparing); - switch (client_state_.mode()) { case wsrep::client_state::m_local: @@ -300,17 +298,37 @@ int wsrep::transaction::before_prepare( ret = 1; } } + if (ret == 0) + { + ret = certify_commit(lock); + assert((ret == 0 && state() == s_preparing) || + (state() == s_must_abort || + state() == s_must_replay || + state() == s_cert_failed)); + + if (ret) + { + assert(state() == s_must_replay || + client_state_.current_error()); + ret = 1; + } + } + break; case wsrep::client_state::m_high_priority: // Note: fragment removal is done from applying // context for high priority mode. + state(lock, s_preparing); break; default: assert(0); break; } - assert(state() == s_preparing || (ret && state() == s_must_abort)); + assert(state() == s_preparing || + (ret && (state() == s_must_abort || + state() == s_must_replay || + state() == s_cert_failed))); debug_log_state("before_prepare_leave"); return ret; } @@ -319,36 +337,22 @@ int wsrep::transaction::after_prepare( wsrep::unique_lock& lock) { assert(lock.owns_lock()); - int ret(1); + debug_log_state("after_prepare_enter"); + assert(certified() && ordered()); assert(state() == s_preparing || state() == s_must_abort); + if (state() == s_must_abort) { assert(client_state_.mode() == wsrep::client_state::m_local); - client_state_.override_error(wsrep::e_deadlock_error); + state(lock, s_must_replay); return 1; } - switch (client_state_.mode()) - { - case wsrep::client_state::m_local: - ret = certify_commit(lock); - assert((ret == 0 && state() == s_committing) || - (state() == s_must_abort || - state() == s_must_replay || - state() == s_cert_failed)); - break; - case wsrep::client_state::m_high_priority: - state(lock, s_certifying); - state(lock, s_committing); - ret = 0; - break; - default: - assert(0); - break; - } + state(lock, s_committing); + debug_log_state("after_prepare_leave"); - return ret; + return 0; } int wsrep::transaction::before_commit() @@ -961,8 +965,8 @@ void wsrep::transaction::state( static const char allowed[n_states][n_states] = { /* ex pr ce co oc ct cf ma ab ad mr re */ { 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0}, /* ex */ - { 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0}, /* pr */ - { 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0}, /* ce */ + { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0}, /* pr */ + { 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0}, /* ce */ { 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0}, /* co */ { 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}, /* ct */ @@ -1331,7 +1335,7 @@ int wsrep::transaction::certify_commit( switch (state()) { case s_certifying: - state(lock, s_committing); + state(lock, s_preparing); ret = 0; break; case s_must_abort: diff --git a/src/wsrep-lib_test.cpp b/src/wsrep-lib_test.cpp deleted file mode 100644 index 41eab1a..0000000 --- a/src/wsrep-lib_test.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2018 Codership Oy - * - * This file is part of wsrep-lib. - * - * Wsrep-lib is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * Wsrep-lib is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with wsrep-lib. If not, see . - */ - -#define BOOST_TEST_MODULE wsrep_test -#include - diff --git a/test/transaction_test_2pc.cpp b/test/transaction_test_2pc.cpp index 6cf4f8c..b6c30c1 100644 --- a/test/transaction_test_2pc.cpp +++ b/test/transaction_test_2pc.cpp @@ -31,6 +31,9 @@ BOOST_FIXTURE_TEST_CASE(transaction_2pc, BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing); BOOST_REQUIRE(cc.before_prepare() == 0); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_preparing); + BOOST_REQUIRE(tc.ordered()); + BOOST_REQUIRE(tc.certified()); + BOOST_REQUIRE(tc.ws_meta().gtid().is_undefined() == false); BOOST_REQUIRE(cc.after_prepare() == 0); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_committing); BOOST_REQUIRE(cc.before_commit() == 0); @@ -85,21 +88,21 @@ BOOST_FIXTURE_TEST_CASE( BOOST_REQUIRE(tc.id() == wsrep::transaction_id(1)); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_executing); BOOST_REQUIRE(cc.before_prepare() == 0); + BOOST_REQUIRE(tc.certified() == true); + BOOST_REQUIRE(tc.ordered() == true); BOOST_REQUIRE(tc.state() == wsrep::transaction::s_preparing); - wsrep_test::bf_abort_unordered(cc); + wsrep_test::bf_abort_ordered(cc); BOOST_REQUIRE(cc.after_prepare()); - BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_abort); - BOOST_REQUIRE(tc.certified() == false); - BOOST_REQUIRE(tc.ordered() == false); + BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay); BOOST_REQUIRE(cc.before_rollback() == 0); - BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborting); + BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay); BOOST_REQUIRE(cc.after_rollback() == 0); - BOOST_REQUIRE(tc.state() == wsrep::transaction::s_aborted); - BOOST_REQUIRE(cc.after_statement() ); + BOOST_REQUIRE(tc.state() == wsrep::transaction::s_must_replay); + BOOST_REQUIRE(cc.after_statement() == 0); BOOST_REQUIRE(tc.active() == false); BOOST_REQUIRE(tc.ordered() == false); BOOST_REQUIRE(tc.certified() == false); - BOOST_REQUIRE(cc.current_error()); + BOOST_REQUIRE(cc.current_error() == wsrep::e_success); } //