diff --git a/dbsim/db_server_service.cpp b/dbsim/db_server_service.cpp index 07b88fa..58ffdf3 100644 --- a/dbsim/db_server_service.cpp +++ b/dbsim/db_server_service.cpp @@ -128,6 +128,11 @@ wsrep::view db::server_service::get_view(wsrep::client_service&, return my_view; } +wsrep::gtid db::server_service::get_position(wsrep::client_service&) +{ + throw wsrep::not_implemented_error(); +} + void db::server_service::log_state_change( enum wsrep::server_state::state prev_state, enum wsrep::server_state::state current_state) diff --git a/dbsim/db_server_service.hpp b/dbsim/db_server_service.hpp index 420becc..cdc474a 100644 --- a/dbsim/db_server_service.hpp +++ b/dbsim/db_server_service.hpp @@ -50,6 +50,7 @@ namespace db const wsrep::view&) override; wsrep::view get_view(wsrep::client_service&, const wsrep::id&) override; + wsrep::gtid get_position(wsrep::client_service&) override; void log_state_change(enum wsrep::server_state::state, enum wsrep::server_state::state) override; int wait_committing_transactions(int) override; diff --git a/dbsim/db_simulator.cpp b/dbsim/db_simulator.cpp index 990d1ac..594b847 100644 --- a/dbsim/db_simulator.cpp +++ b/dbsim/db_simulator.cpp @@ -67,7 +67,7 @@ void db::simulator::sst(db::server& server, db::client dummy(*(i->second), wsrep::client_id(-1), wsrep::client_state::m_local, params()); - i->second->server_state().sst_received(dummy.client_service(), gtid, 0); + i->second->server_state().sst_received(dummy.client_service(), 0); server.server_state().sst_sent(gtid, 0); } diff --git a/include/wsrep/server_service.hpp b/include/wsrep/server_service.hpp index df2cbc8..8c513b5 100644 --- a/include/wsrep/server_service.hpp +++ b/include/wsrep/server_service.hpp @@ -141,6 +141,16 @@ namespace wsrep wsrep::client_service& client_service, const wsrep::id& own_id) = 0; + /** + * Get the current replication position from the server + * storage. + * + * @param client_service Reference to client_service + * + * @return Current position GTID. + */ + virtual wsrep::gtid get_position( + wsrep::client_service& client_service) = 0; /** * Log a state change event. * diff --git a/include/wsrep/server_state.hpp b/include/wsrep/server_state.hpp index 2f67e45..46f686a 100644 --- a/include/wsrep/server_state.hpp +++ b/include/wsrep/server_state.hpp @@ -460,11 +460,9 @@ namespace wsrep * and will wait until the initialization is complete. * * @param client_service - * @param gtid GTID provided by the SST transfer * @param error code of the SST operation */ - void sst_received(wsrep::client_service& cs, - const wsrep::gtid& gtid, int error); + void sst_received(wsrep::client_service& cs, int error); /** * This method must be called after the server initialization diff --git a/src/server_state.cpp b/src/server_state.cpp index b90c7a9..cdc9a26 100644 --- a/src/server_state.cpp +++ b/src/server_state.cpp @@ -524,16 +524,16 @@ void wsrep::server_state::sst_sent(const wsrep::gtid& gtid, int error) } void wsrep::server_state::sst_received(wsrep::client_service& cs, - const wsrep::gtid& gtid, int const error) { - wsrep::log_info() << "SST received: " << gtid; + wsrep::log_info() << "SST received"; + wsrep::gtid gtid(wsrep::gtid::undefined()); wsrep::unique_lock lock(mutex_); assert(state_ == s_joiner || state_ == s_initialized); // Run initialization only if the SST was successful. // In case of SST failure the system is in undefined state - // may not be recoverable. + // may not be recoverable. if (error == 0) { if (server_service_.sst_before_init()) @@ -558,6 +558,8 @@ void wsrep::server_state::sst_received(wsrep::client_service& cs, "wsrep::sst_received() called before connection to cluster"); } + gtid = server_service_.get_position(cs); + wsrep::log_info() << "Recovered position from storage: " << gtid; wsrep::view const v(server_service_.get_view(cs, id_)); wsrep::log_info() << "Recovered view from SST:\n" << v; diff --git a/test/mock_server_state.hpp b/test/mock_server_state.hpp index 7826a92..2d7ecc2 100644 --- a/test/mock_server_state.hpp +++ b/test/mock_server_state.hpp @@ -42,6 +42,7 @@ namespace wsrep , last_client_id_(0) , last_transaction_id_(0) , logged_view_() + , position_() { } wsrep::storage_service* storage_service(wsrep::client_service&) @@ -143,6 +144,10 @@ namespace wsrep return my_view; } + wsrep::gtid get_position(wsrep::client_service&) WSREP_OVERRIDE + { + return position_; + } void log_state_change(enum wsrep::server_state::state, enum wsrep::server_state::state) { } @@ -198,11 +203,16 @@ namespace wsrep { logged_view_ = view; } + void position(const wsrep::gtid& position) + { + position_ = position; + } private: wsrep::server_state& server_state_; unsigned long long last_client_id_; unsigned long long last_transaction_id_; wsrep::view logged_view_; + wsrep::gtid position_; }; diff --git a/test/server_context_test.cpp b/test/server_context_test.cpp index 835ad51..09ece5a 100644 --- a/test/server_context_test.cpp +++ b/test/server_context_test.cpp @@ -338,7 +338,8 @@ BOOST_FIXTURE_TEST_CASE(server_state_sst_first_join_with_sst, // Get_view() is called from sst_received(). This emulates the // case where SST contains the view in which SST happens. server_service.logged_view(second_view); - ss.sst_received(cc, wsrep::gtid(cluster_id, wsrep::seqno(2)), 0); + server_service.position(wsrep::gtid(cluster_id, wsrep::seqno(2))); + ss.sst_received(cc, 0); clear_sync_point_action(); BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joined); ss.on_sync(); @@ -423,8 +424,8 @@ BOOST_FIXTURE_TEST_CASE( connect_in_view(second_view); ss.prepare_for_sst(); BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joiner); - ss.sst_received(cc, wsrep::gtid(wsrep::id::undefined(), - wsrep::seqno::undefined()), 1); + server_service.position(wsrep::gtid::undefined()); + ss.sst_received(cc, 1); disconnect(); } @@ -436,7 +437,8 @@ BOOST_FIXTURE_TEST_CASE( ss.prepare_for_sst(); BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joiner); initialization_failure_action(); - BOOST_REQUIRE_EXCEPTION(ss.sst_received(cc, second_view.state_id(), 0), + server_service.position(wsrep::gtid(second_view.state_id())); + BOOST_REQUIRE_EXCEPTION(ss.sst_received(cc, 0), wsrep::runtime_error, exception_check); BOOST_REQUIRE(ss.state() == wsrep::server_state::s_initializing); BOOST_REQUIRE_EXCEPTION(ss.on_view(second_view, &hps), @@ -459,7 +461,8 @@ BOOST_FIXTURE_TEST_CASE( // Get_view() is called from sst_received(). This emulates the // case where SST contains the view in which SST happens. server_service.logged_view(second_view); - ss.sst_received(cc, wsrep::gtid(cluster_id, wsrep::seqno(2)), 0); + server_service.position(wsrep::gtid(cluster_id, wsrep::seqno(2))); + ss.sst_received(cc, 0); clear_sync_point_action(); BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joined); disconnect(); @@ -499,7 +502,8 @@ BOOST_FIXTURE_TEST_CASE(server_state_init_first_join_with_sst, prepare_for_sst(); BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joiner); server_service.logged_view(second_view); - ss.sst_received(cc, wsrep::gtid(cluster_id, wsrep::seqno(2)), 0); + server_service.position(wsrep::gtid(cluster_id, wsrep::seqno(2))); + ss.sst_received(cc, 0); BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joined); ss.on_sync(); BOOST_REQUIRE(ss.state() == wsrep::server_state::s_synced);