Skip to content

Commit d39a974

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 85b8150 commit d39a974

File tree

4 files changed

+49
-4
lines changed

4 files changed

+49
-4
lines changed

include/wsrep/server_state.hpp

+4-3
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

+21-1
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

+8
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

+16
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)