Skip to content

Commit a06b5ab

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 209c214 commit a06b5ab

File tree

4 files changed

+49
-4
lines changed

4 files changed

+49
-4
lines changed

include/wsrep/server_state.hpp

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

95-
#include <vector>
96-
#include <string>
95+
#include <atomic>
9796
#include <map>
97+
#include <string>
98+
#include <vector>
9899

99100
/**
100101
* Magic string to tell provider to engage into trivial (empty)
@@ -679,7 +680,7 @@ namespace wsrep
679680
mutable std::vector<int> state_waiters_;
680681
bool bootstrap_;
681682
const wsrep::gtid initial_position_;
682-
bool init_initialized_;
683+
std::atomic<bool> init_initialized_;
683684
bool init_synced_;
684685
wsrep::gtid sst_gtid_;
685686
size_t desync_count_;

src/server_state.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,26 @@ int wsrep::server_state::on_apply(
11211121
const wsrep::ws_meta& ws_meta,
11221122
const wsrep::const_buffer& data)
11231123
{
1124+
if (not init_initialized_.load())
1125+
{
1126+
wsrep::unique_lock<wsrep::mutex> lock(mutex_);
1127+
if (state(lock) == s_connected)
1128+
{
1129+
state(lock, s_initializing);
1130+
lock.unlock();
1131+
server_service_.debug_sync("on_view_wait_initialized");
1132+
lock.lock();
1133+
}
1134+
while (not init_initialized_.load())
1135+
{
1136+
wait_until_state(lock, s_initialized);
1137+
}
1138+
if (state(lock) == s_initialized)
1139+
{
1140+
state(lock, s_joined);
1141+
}
1142+
}
1143+
11241144
if (is_toi(ws_meta.flags()))
11251145
{
11261146
return apply_toi(provider(), high_priority_service,
@@ -1353,7 +1373,7 @@ void wsrep::server_state::state(
13531373
{ 0, 1, 0, 1, 0, 0, 0, 0, 0}, /* dis */
13541374
{ 1, 0, 1, 0, 0, 0, 0, 0, 1}, /* ing */
13551375
{ 1, 0, 0, 1, 0, 1, 0, 0, 1}, /* ized */
1356-
{ 1, 0, 0, 1, 1, 0, 0, 1, 1}, /* cted */
1376+
{ 1, 1, 0, 1, 1, 0, 0, 1, 1}, /* cted */
13571377
{ 1, 1, 0, 0, 0, 1, 0, 0, 1}, /* jer */
13581378
{ 1, 0, 0, 1, 0, 0, 1, 1, 1}, /* jed */
13591379
{ 1, 0, 0, 1, 0, 1, 0, 1, 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)