Skip to content

Commit 313d7d2

Browse files
committed
Enable DBMS initialization from applying codepath
In general the provider might not guarantee that after joining to replication group, the first applied event is view event. Made init_initialized_ atomic and check it also from applying codepath. If the DBMS is not yet initialized when applying the first event, change state to initializing and wait for DBMS initialization completion. Notes: - Allow connected -> initializing state change. - Handle bootstrap_view in mock_connect to make server state synced for tests.
1 parent 6fd1fdf commit 313d7d2

File tree

4 files changed

+49
-2
lines changed

4 files changed

+49
-2
lines changed

include/wsrep/server_state.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,13 @@
9292
#include "compiler.hpp"
9393
#include "xid.hpp"
9494

95+
#include <atomic>
9596
#include <deque>
9697
#include <vector>
9798
#include <string>
9899
#include <map>
100+
#include <string>
101+
#include <vector>
99102

100103
/**
101104
* Magic string to tell provider to engage into trivial (empty)
@@ -686,7 +689,7 @@ namespace wsrep
686689
mutable std::vector<int> state_waiters_;
687690
bool bootstrap_;
688691
const wsrep::gtid initial_position_;
689-
bool init_initialized_;
692+
std::atomic<bool> init_initialized_;
690693
bool init_synced_;
691694
wsrep::gtid sst_gtid_;
692695
size_t desync_count_;

src/server_state.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1098,6 +1098,26 @@ int wsrep::server_state::on_apply(
10981098
const wsrep::ws_meta& ws_meta,
10991099
const wsrep::const_buffer& data)
11001100
{
1101+
if (not init_initialized_.load())
1102+
{
1103+
wsrep::unique_lock<wsrep::mutex> lock(mutex_);
1104+
if (state(lock) == s_connected)
1105+
{
1106+
state(lock, s_initializing);
1107+
lock.unlock();
1108+
server_service_.debug_sync("on_view_wait_initialized");
1109+
lock.lock();
1110+
}
1111+
while (not init_initialized_.load())
1112+
{
1113+
wait_until_state(lock, s_initialized);
1114+
}
1115+
if (state(lock) == s_initialized)
1116+
{
1117+
state(lock, s_joined);
1118+
}
1119+
}
1120+
11011121
if (is_toi(ws_meta.flags()))
11021122
{
11031123
return apply_toi(provider(), high_priority_service,
@@ -1330,7 +1350,7 @@ void wsrep::server_state::state(
13301350
{ 0, 1, 0, 1, 0, 0, 0, 0, 0}, /* dis */
13311351
{ 1, 0, 1, 0, 0, 0, 0, 0, 1}, /* ing */
13321352
{ 1, 0, 0, 1, 0, 1, 0, 0, 1}, /* ized */
1333-
{ 1, 0, 0, 1, 1, 0, 0, 1, 1}, /* cted */
1353+
{ 1, 1, 0, 1, 1, 0, 0, 1, 1}, /* cted */
13341354
{ 1, 1, 0, 0, 0, 1, 0, 0, 1}, /* jer */
13351355
{ 1, 0, 0, 1, 0, 0, 1, 1, 1}, /* jed */
13361356
{ 1, 0, 0, 1, 0, 1, 0, 0, 1}, /* dor */

test/mock_server_state.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,14 @@ namespace wsrep
278278
1,
279279
members);
280280
server_state::on_connect(bootstrap_view);
281+
server_state::initialized();
282+
wsrep::mock_client cs(*this, wsrep::client_id(0),
283+
wsrep::client_state::m_high_priority);
284+
wsrep::mock_high_priority_service hps(*this, &cs, false);
285+
server_state::on_view(bootstrap_view, &hps);
286+
BOOST_REQUIRE(state() == wsrep::server_state::s_joined);
287+
server_state::on_sync();
288+
BOOST_REQUIRE(state() == wsrep::server_state::s_synced);
281289
}
282290
else
283291
{

test/server_context_test.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,22 @@ BOOST_FIXTURE_TEST_CASE(
485485
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_disconnected);
486486
}
487487

488+
BOOST_FIXTURE_TEST_CASE(
489+
server_state_sst_first_init_on_apply,
490+
sst_first_server_fixture)
491+
{
492+
connect_in_view(second_view);
493+
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_connected);
494+
sst_received_action();
495+
char buf[1] = { 1 };
496+
BOOST_REQUIRE(ss.on_apply(hps, ws_handle, ws_meta,
497+
wsrep::const_buffer(buf, 1)) == 0);
498+
const wsrep::transaction& txc(cc.transaction());
499+
BOOST_REQUIRE(txc.state() == wsrep::transaction::s_committed);
500+
BOOST_REQUIRE(ss.state() == wsrep::server_state::s_joined);
501+
502+
}
503+
488504
///////////////////////////////////////////////////////////////////////////////
489505
// Test cases for init first //
490506
///////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)