mirror of
https://github.com/codership/wsrep-lib.git
synced 2025-07-28 20:02:00 +03:00
Read recovered position from sst_received() after initialization
In general the position where the storage recovers after a SST cannot be known untile the recovery process is over. This in turn means that the position cannot be known when the server_state sst_received() method is called. Worked around the problem by introducing get_position() method into server service which can be used to get the position from stable storage after SST has completed and the state has been recovered.
This commit is contained in:
@ -128,6 +128,11 @@ wsrep::view db::server_service::get_view(wsrep::client_service&,
|
|||||||
return my_view;
|
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(
|
void db::server_service::log_state_change(
|
||||||
enum wsrep::server_state::state prev_state,
|
enum wsrep::server_state::state prev_state,
|
||||||
enum wsrep::server_state::state current_state)
|
enum wsrep::server_state::state current_state)
|
||||||
|
@ -50,6 +50,7 @@ namespace db
|
|||||||
const wsrep::view&) override;
|
const wsrep::view&) override;
|
||||||
wsrep::view get_view(wsrep::client_service&, const wsrep::id&)
|
wsrep::view get_view(wsrep::client_service&, const wsrep::id&)
|
||||||
override;
|
override;
|
||||||
|
wsrep::gtid get_position(wsrep::client_service&) override;
|
||||||
void log_state_change(enum wsrep::server_state::state,
|
void log_state_change(enum wsrep::server_state::state,
|
||||||
enum wsrep::server_state::state) override;
|
enum wsrep::server_state::state) override;
|
||||||
int wait_committing_transactions(int) override;
|
int wait_committing_transactions(int) override;
|
||||||
|
@ -67,7 +67,7 @@ void db::simulator::sst(db::server& server,
|
|||||||
db::client dummy(*(i->second), wsrep::client_id(-1),
|
db::client dummy(*(i->second), wsrep::client_id(-1),
|
||||||
wsrep::client_state::m_local, params());
|
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);
|
server.server_state().sst_sent(gtid, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,6 +141,16 @@ namespace wsrep
|
|||||||
wsrep::client_service& client_service,
|
wsrep::client_service& client_service,
|
||||||
const wsrep::id& own_id) = 0;
|
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.
|
* Log a state change event.
|
||||||
*
|
*
|
||||||
|
@ -460,11 +460,9 @@ namespace wsrep
|
|||||||
* and will wait until the initialization is complete.
|
* and will wait until the initialization is complete.
|
||||||
*
|
*
|
||||||
* @param client_service
|
* @param client_service
|
||||||
* @param gtid GTID provided by the SST transfer
|
|
||||||
* @param error code of the SST operation
|
* @param error code of the SST operation
|
||||||
*/
|
*/
|
||||||
void sst_received(wsrep::client_service& cs,
|
void sst_received(wsrep::client_service& cs, int error);
|
||||||
const wsrep::gtid& gtid, int error);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method must be called after the server initialization
|
* This method must be called after the server initialization
|
||||||
|
@ -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,
|
void wsrep::server_state::sst_received(wsrep::client_service& cs,
|
||||||
const wsrep::gtid& gtid,
|
|
||||||
int const error)
|
int const error)
|
||||||
{
|
{
|
||||||
wsrep::log_info() << "SST received: " << gtid;
|
wsrep::log_info() << "SST received";
|
||||||
|
wsrep::gtid gtid(wsrep::gtid::undefined());
|
||||||
wsrep::unique_lock<wsrep::mutex> lock(mutex_);
|
wsrep::unique_lock<wsrep::mutex> lock(mutex_);
|
||||||
assert(state_ == s_joiner || state_ == s_initialized);
|
assert(state_ == s_joiner || state_ == s_initialized);
|
||||||
|
|
||||||
// Run initialization only if the SST was successful.
|
// Run initialization only if the SST was successful.
|
||||||
// In case of SST failure the system is in undefined state
|
// In case of SST failure the system is in undefined state
|
||||||
// may not be recoverable.
|
// may not be recoverable.
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
{
|
{
|
||||||
if (server_service_.sst_before_init())
|
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");
|
"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::view const v(server_service_.get_view(cs, id_));
|
||||||
wsrep::log_info() << "Recovered view from SST:\n" << v;
|
wsrep::log_info() << "Recovered view from SST:\n" << v;
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ namespace wsrep
|
|||||||
, last_client_id_(0)
|
, last_client_id_(0)
|
||||||
, last_transaction_id_(0)
|
, last_transaction_id_(0)
|
||||||
, logged_view_()
|
, logged_view_()
|
||||||
|
, position_()
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
wsrep::storage_service* storage_service(wsrep::client_service&)
|
wsrep::storage_service* storage_service(wsrep::client_service&)
|
||||||
@ -143,6 +144,10 @@ namespace wsrep
|
|||||||
return my_view;
|
return my_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wsrep::gtid get_position(wsrep::client_service&) WSREP_OVERRIDE
|
||||||
|
{
|
||||||
|
return position_;
|
||||||
|
}
|
||||||
void log_state_change(enum wsrep::server_state::state,
|
void log_state_change(enum wsrep::server_state::state,
|
||||||
enum wsrep::server_state::state)
|
enum wsrep::server_state::state)
|
||||||
{ }
|
{ }
|
||||||
@ -198,11 +203,16 @@ namespace wsrep
|
|||||||
{
|
{
|
||||||
logged_view_ = view;
|
logged_view_ = view;
|
||||||
}
|
}
|
||||||
|
void position(const wsrep::gtid& position)
|
||||||
|
{
|
||||||
|
position_ = position;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
wsrep::server_state& server_state_;
|
wsrep::server_state& server_state_;
|
||||||
unsigned long long last_client_id_;
|
unsigned long long last_client_id_;
|
||||||
unsigned long long last_transaction_id_;
|
unsigned long long last_transaction_id_;
|
||||||
wsrep::view logged_view_;
|
wsrep::view logged_view_;
|
||||||
|
wsrep::gtid position_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
// Get_view() is called from sst_received(). This emulates the
|
||||||
// case where SST contains the view in which SST happens.
|
// case where SST contains the view in which SST happens.
|
||||||
server_service.logged_view(second_view);
|
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();
|
clear_sync_point_action();
|
||||||
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joined);
|
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joined);
|
||||||
ss.on_sync();
|
ss.on_sync();
|
||||||
@ -423,8 +424,8 @@ BOOST_FIXTURE_TEST_CASE(
|
|||||||
connect_in_view(second_view);
|
connect_in_view(second_view);
|
||||||
ss.prepare_for_sst();
|
ss.prepare_for_sst();
|
||||||
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joiner);
|
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joiner);
|
||||||
ss.sst_received(cc, wsrep::gtid(wsrep::id::undefined(),
|
server_service.position(wsrep::gtid::undefined());
|
||||||
wsrep::seqno::undefined()), 1);
|
ss.sst_received(cc, 1);
|
||||||
disconnect();
|
disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,7 +437,8 @@ BOOST_FIXTURE_TEST_CASE(
|
|||||||
ss.prepare_for_sst();
|
ss.prepare_for_sst();
|
||||||
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joiner);
|
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joiner);
|
||||||
initialization_failure_action();
|
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);
|
wsrep::runtime_error, exception_check);
|
||||||
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_initializing);
|
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_initializing);
|
||||||
BOOST_REQUIRE_EXCEPTION(ss.on_view(second_view, &hps),
|
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
|
// Get_view() is called from sst_received(). This emulates the
|
||||||
// case where SST contains the view in which SST happens.
|
// case where SST contains the view in which SST happens.
|
||||||
server_service.logged_view(second_view);
|
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();
|
clear_sync_point_action();
|
||||||
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joined);
|
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joined);
|
||||||
disconnect();
|
disconnect();
|
||||||
@ -499,7 +502,8 @@ BOOST_FIXTURE_TEST_CASE(server_state_init_first_join_with_sst,
|
|||||||
prepare_for_sst();
|
prepare_for_sst();
|
||||||
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joiner);
|
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joiner);
|
||||||
server_service.logged_view(second_view);
|
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);
|
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joined);
|
||||||
ss.on_sync();
|
ss.on_sync();
|
||||||
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_synced);
|
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_synced);
|
||||||
|
Reference in New Issue
Block a user