1
0
mirror of https://github.com/codership/wsrep-lib.git synced 2025-07-30 07:23:07 +03:00

Allow server_state joiner - disconnecting transition.

Transition joiner - disconnecting may happen when the joiner failed
to receive SST succesfully. Because the system is at undefined state
at this point, skip most of the processing in sst_received()
and return control to caller after notifying the provider about
failure.
This commit is contained in:
Teemu Ollakka
2018-12-19 14:30:19 +02:00
parent e81c66cd59
commit 7cd0656990
2 changed files with 38 additions and 24 deletions

View File

@ -520,12 +520,26 @@ 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 error) const wsrep::gtid& gtid,
int const error)
{ {
wsrep::log_info() << "SST received: " << gtid; wsrep::log_info() << "SST received: " << gtid;
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);
// Deal with error case first. If the SST failed, the system
// may be in unrecoverable state. There is no point of doing
// anything else then notifying the provider about failure
// and returning control back to caller.
if (error)
{
if (provider().sst_received(gtid, error))
{
throw wsrep::runtime_error("wsrep::sst_received() failed");
}
return;
}
if (server_service_.sst_before_init()) if (server_service_.sst_before_init())
{ {
if (init_initialized_ == false) if (init_initialized_ == false)
@ -548,8 +562,6 @@ 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");
} }
if (0 == error) /* SST was a success, recover view */
{
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;
@ -570,7 +582,6 @@ void wsrep::server_state::sst_received(wsrep::client_service& cs,
current_view_ = v; current_view_ = v;
server_service_.log_view(NULL /* this view is stored already */, v); server_service_.log_view(NULL /* this view is stored already */, v);
}
if (provider().sst_received(gtid, error)) if (provider().sst_received(gtid, error))
{ {
@ -1076,7 +1087,7 @@ void wsrep::server_state::state(
{ 1, 0, 1, 0, 0, 0, 0, 0, 0}, /* ing */ { 1, 0, 1, 0, 0, 0, 0, 0, 0}, /* ing */
{ 1, 0, 0, 1, 0, 1, 0, 0, 0}, /* ized */ { 1, 0, 0, 1, 0, 1, 0, 0, 0}, /* ized */
{ 1, 0, 0, 1, 1, 0, 0, 1, 1}, /* cted */ { 1, 0, 0, 1, 1, 0, 0, 1, 1}, /* cted */
{ 1, 1, 0, 0, 0, 1, 0, 0, 0}, /* jer */ { 1, 1, 0, 0, 0, 1, 0, 0, 1}, /* jer */
{ 1, 0, 0, 1, 0, 0, 0, 1, 1}, /* jed */ { 1, 0, 0, 1, 0, 0, 0, 1, 1}, /* jed */
{ 1, 0, 0, 0, 0, 1, 0, 0, 1}, /* dor */ { 1, 0, 0, 0, 0, 1, 0, 0, 1}, /* dor */
{ 1, 0, 0, 1, 0, 1, 1, 0, 1}, /* sed */ { 1, 0, 0, 1, 0, 1, 1, 0, 1}, /* sed */

View File

@ -371,7 +371,7 @@ BOOST_FIXTURE_TEST_CASE(
disconnect(); disconnect();
} }
// Error during SST.q // Error during SST.
BOOST_FIXTURE_TEST_CASE( BOOST_FIXTURE_TEST_CASE(
server_state_sst_first_error_on_joiner, server_state_sst_first_error_on_joiner,
sst_first_server_fixture) sst_first_server_fixture)
@ -379,6 +379,9 @@ 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(),
wsrep::seqno::undefined()), 1);
disconnect();
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////