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

Fix assertion unallowed state transition: connected -> joined

When the donor lost its donor state during SST due to cluster
partitioning, the state was erranously changed to `s_joined`
in `start_sst()` and `sst_sent()`, which caused assertion failures
in state checking.

Fixed by changing state to `s_joined` only if donor is still in
`s_donor` state.
This commit is contained in:
Teemu Ollakka
2023-02-26 11:43:44 +02:00
parent 3b3429d8df
commit 5a943b66a7
3 changed files with 77 additions and 12 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2019 Codership Oy <info@codership.com>
* Copyright (C) 2018-2013 Codership Oy <info@codership.com>
*
* This file is part of wsrep-lib.
*
@ -172,11 +172,20 @@ namespace wsrep
bool sst_before_init() const WSREP_OVERRIDE
{ return sst_before_init_; }
std::string sst_request() WSREP_OVERRIDE { return ""; }
int start_sst(const std::string&,
const wsrep::gtid&,
bool) WSREP_OVERRIDE { return 0; }
void background_rollback(wsrep::client_state& client_state)
WSREP_OVERRIDE
std::function<int()> start_sst_action{};
int start_sst(const std::string&, const wsrep::gtid&,
bool) WSREP_OVERRIDE
{
if (start_sst_action)
{
return start_sst_action();
}
return 0;
}
void
background_rollback(wsrep::client_state& client_state) WSREP_OVERRIDE
{
client_state.before_rollback();
client_state.after_rollback();

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2019 Codership Oy <info@codership.com>
* Copyright (C) 2018-2023 Codership Oy <info@codership.com>
*
* This file is part of wsrep-lib.
*
@ -105,6 +105,24 @@ namespace
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joiner);
}
void non_prim()
{
BOOST_REQUIRE(ss.state() != wsrep::server_state::s_disconnected);
std::vector<wsrep::view::member> members;
members.push_back(wsrep::view::member(
ss.id(), "s1", ""));
wsrep::view view(wsrep::gtid(), // state_id
wsrep::seqno::undefined(), // view seqno
wsrep::view::non_primary, // status
0, // capabilities
0, // own_index
0, // protocol ver
members // members
);
ss.on_view(view, &hps);
}
void final_view()
{
BOOST_REQUIRE(ss.state() != wsrep::server_state::s_disconnected);
@ -599,6 +617,35 @@ BOOST_FIXTURE_TEST_CASE(
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_synced);
}
BOOST_FIXTURE_TEST_CASE(
server_state_sst_first_donor_start_sst_error_in_non_prim,
sst_first_server_fixture)
{
bootstrap();
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_synced);
server_service.start_sst_action = [&]() {
non_prim();
return 1;
};
ss.start_sst("", wsrep::gtid(cluster_id, wsrep::seqno(2)), false);
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_connected);
}
BOOST_FIXTURE_TEST_CASE(
server_state_sst_first_donor_sst_sent_in_non_prim,
sst_first_server_fixture)
{
bootstrap();
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_synced);
ss.start_sst("", wsrep::gtid(cluster_id, wsrep::seqno(2)), false);
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_donor);
non_prim();
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_connected);
ss.sst_sent(wsrep::gtid(cluster_id, wsrep::seqno(2)), 0);
// Must stay in connected state
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_connected);
}
/////////////////////////////////////////////////////////////////////////////
// Pause/Resume and Desync/Resync //
/////////////////////////////////////////////////////////////////////////////