Skip to content

Commit 488c259

Browse files
committed
- Initialize member cluster ID only on connection to cluster and forget
it on disconnect. - Don't rely on own index from the view because the view may come from another member (IST/SST), instead always determine own index from own ID. Refs #13
1 parent d4efa59 commit 488c259

13 files changed

+185
-52
lines changed

dbsim/db_server.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,14 @@
2727

2828
db::server::server(simulator& simulator,
2929
const std::string& name,
30-
const std::string& server_id,
3130
const std::string& address)
3231
: simulator_(simulator)
3332
, storage_engine_(simulator_.params())
3433
, mutex_()
3534
, cond_()
3635
, server_service_(*this)
3736
, server_state_(*this, server_service_,
38-
name, server_id, address, "dbsim_" + name + "_data")
37+
name, address, "dbsim_" + name + "_data")
3938
, last_client_id_(0)
4039
, last_transaction_id_(0)
4140
, appliers_()

dbsim/db_server.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ namespace db
4141
public:
4242
server(simulator& simulator,
4343
const std::string& name,
44-
const std::string& id,
4544
const std::string& address);
4645
void applier_thread();
4746
void start_applier();

dbsim/db_server_state.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,13 @@ namespace db
3535
server_state(db::server& server,
3636
wsrep::server_service& server_service,
3737
const std::string& name,
38-
const std::string& server_id,
3938
const std::string& address,
4039
const std::string& working_dir)
4140
: wsrep::server_state(
4241
mutex_,
4342
cond_,
4443
server_service,
4544
name,
46-
server_id,
4745
"",
4846
address,
4947
working_dir,

dbsim/db_simulator.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ void db::simulator::start()
109109
std::make_unique<db::server>(
110110
*this,
111111
name_os.str(),
112-
id_os.str(),
113112
address_os.str()))));
114113
if (it.second == false)
115114
{

include/wsrep/server_state.hpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ namespace wsrep
296296
* A method which will be called when the server
297297
* has been joined to the cluster
298298
*/
299-
void on_connect(const wsrep::gtid& gtid);
299+
void on_connect(const wsrep::view& view);
300300

301301
/**
302302
* A method which will be called when a view
@@ -540,7 +540,6 @@ namespace wsrep
540540
wsrep::condition_variable& cond,
541541
wsrep::server_service& server_service,
542542
const std::string& name,
543-
const std::string& id,
544543
const std::string& incoming_address,
545544
const std::string& address,
546545
const std::string& working_dir,
@@ -565,7 +564,7 @@ namespace wsrep
565564
, streaming_appliers_()
566565
, provider_()
567566
, name_(name)
568-
, id_(id)
567+
, id_(wsrep::id::undefined())
569568
, incoming_address_(incoming_address)
570569
, address_(address)
571570
, working_dir_(working_dir)

include/wsrep/view.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "seqno.hpp"
3131
#include "gtid.hpp"
3232
#include <vector>
33+
#include <iostream>
3334

3435
namespace wsrep
3536
{
@@ -111,6 +112,8 @@ namespace wsrep
111112
return (members_.empty() && own_index_ == -1);
112113
}
113114

115+
void print(std::ostream& os) const;
116+
114117
private:
115118
wsrep::gtid state_id_;
116119
wsrep::seqno view_seqno_;
@@ -120,6 +123,12 @@ namespace wsrep
120123
int protocol_version_;
121124
std::vector<wsrep::view::member> members_;
122125
};
126+
127+
static inline
128+
std::ostream& operator<<(std::ostream& os, const wsrep::view& v)
129+
{
130+
v.print(os); return os;
131+
}
123132
}
124133

125134
#endif // WSREP_VIEW

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ add_library(wsrep-lib
1111
logger.cpp
1212
provider.cpp
1313
seqno.cpp
14+
view.cpp
1415
server_state.cpp
1516
transaction.cpp
1617
wsrep_provider_v26.cpp)

src/server_state.cpp

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -565,14 +565,38 @@ wsrep::server_state::causal_read(int timeout) const
565565
return provider_->causal_read(timeout);
566566
}
567567

568-
void wsrep::server_state::on_connect(const wsrep::gtid& gtid)
568+
void wsrep::server_state::on_connect(const wsrep::view& view)
569569
{
570+
// Sanity checks
571+
if (id_.is_undefined() == false)
572+
{
573+
wsrep::log_warning() << "Unexpected connection in connected state. "
574+
<< "Received view: " << view
575+
<< "Previous ID: " << id_;
576+
assert(0);
577+
}
578+
579+
if (view.own_index() < 0 ||
580+
size_t(view.own_index()) >= view.members().size())
581+
{
582+
std::ostringstream os;
583+
os << "Invalid view on connect: own index out of range: " << view;
584+
wsrep::log_error() << os.str();
585+
assert(0);
586+
throw wsrep::runtime_error(os.str());
587+
}
588+
589+
id_ = view.members()[view.own_index()].id();
590+
570591
wsrep::log_info() << "Server "
571592
<< name_
572593
<< " connected to cluster at position "
573-
<< gtid;
594+
<< view.state_id()
595+
<< " with ID "
596+
<< id_;
597+
574598
wsrep::unique_lock<wsrep::mutex> lock(mutex_);
575-
connected_gtid_ = gtid;
599+
connected_gtid_ = view.state_id();
576600
state(lock, s_connected);
577601
}
578602

@@ -599,22 +623,7 @@ void wsrep::server_state::on_view(const wsrep::view& view,
599623
if (view.status() == wsrep::view::primary)
600624
{
601625
wsrep::unique_lock<wsrep::mutex> lock(mutex_);
602-
if (view.own_index() >= 0)
603-
{
604-
if (id_.is_undefined())
605-
{
606-
// No identifier was passed during server state initialization
607-
// and the ID was generated by the provider.
608-
id_ = view.members()[view.own_index()].id();
609-
}
610-
else
611-
{
612-
// Own identifier must not change between views.
613-
// assert(id_ == view.members()[view.own_index()].id());
614-
}
615-
}
616626
assert(view.final() == false);
617-
618627
//
619628
// Reached primary from connected state. This may mean the following
620629
//
@@ -703,6 +712,7 @@ void wsrep::server_state::on_view(const wsrep::view& view,
703712
{
704713
close_transactions_at_disconnect(*high_priority_service);
705714
}
715+
id_ = id::undefined();
706716
state(lock, s_disconnected);
707717
}
708718
else if (state_ != s_disconnecting)

src/view.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (C) 2018 Codership Oy <[email protected]>
3+
*
4+
* This file is part of wsrep-lib.
5+
*
6+
* Wsrep-lib is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 2 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Wsrep-lib is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with wsrep-lib. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
#include "wsrep/view.hpp"
21+
22+
void wsrep::view::print(std::ostream& os) const
23+
{
24+
os << " id: " << state_id() << "\n"
25+
<< " status: " << status() << "\n"
26+
<< " prococol_version: " << protocol_version() << "\n"
27+
<< " final: " << final() << "\n"
28+
<< " own_index: " << own_index() << "\n"
29+
<< " members(" << members().size() << "):\n";
30+
31+
for (std::vector<wsrep::view::member>::const_iterator i(members().begin());
32+
i != members().end(); ++i)
33+
{
34+
os << "\t" << (i - members().begin()) /* ordinal index */
35+
<< ") id: " << i->id()
36+
<< ", name: " << i->name() << "\n";
37+
}
38+
}

src/wsrep_provider_v26.cpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,8 @@ namespace
287287
{
288288
return capabilities;
289289
}
290-
wsrep::view view_from_native(const wsrep_view_info& view_info)
290+
wsrep::view view_from_native(const wsrep_view_info& view_info,
291+
const wsrep::id& own_id)
291292
{
292293
std::vector<wsrep::view::member> members;
293294
for (int i(0); i < view_info.memb_num; ++i)
@@ -303,6 +304,25 @@ namespace
303304
sizeof(view_info.members[i].incoming)));
304305
members.push_back(wsrep::view::member(id, name, incoming));
305306
}
307+
308+
int own_idx(-1);
309+
if (own_id.is_undefined())
310+
{
311+
// If own ID is undefined, obtain it from the view. This is
312+
// the case on the initial connect to cluster.
313+
own_idx = view_info.my_idx;
314+
}
315+
else
316+
{
317+
// If the node has already obtained its ID from cluster,
318+
// its position in the view (or lack thereof) must be determined
319+
// by the ID.
320+
for (size_t i(0); i < members.size(); ++i)
321+
{
322+
if (own_id == members[i].id()) { own_idx = i; break; }
323+
}
324+
}
325+
306326
return wsrep::view(
307327
wsrep::gtid(
308328
wsrep::id(view_info.state_id.uuid.data,
@@ -311,7 +331,7 @@ namespace
311331
wsrep::seqno(view_info.view),
312332
map_view_status_from_native(view_info.status),
313333
map_capabilities_from_native(view_info.capabilities),
314-
view_info.my_idx,
334+
own_idx,
315335
view_info.proto_ver,
316336
members);
317337
}
@@ -325,12 +345,14 @@ namespace
325345
const wsrep_view_info_t* view_info)
326346
{
327347
assert(app_ctx);
328-
wsrep::view view(view_from_native(*view_info));
329348
wsrep::server_state& server_state(
330349
*reinterpret_cast<wsrep::server_state*>(app_ctx));
350+
assert(server_state.id().is_undefined());
351+
wsrep::view view(view_from_native(*view_info, server_state.id()));
352+
assert(view.own_index() >= 0);
331353
try
332354
{
333-
server_state.on_connect(view.state_id());
355+
server_state.on_connect(view);
334356
return WSREP_CB_SUCCESS;
335357
}
336358
catch (const wsrep::runtime_error& e)
@@ -354,7 +376,7 @@ namespace
354376
reinterpret_cast<wsrep::high_priority_service*>(recv_ctx));
355377
try
356378
{
357-
wsrep::view view(view_from_native(*view_info));
379+
wsrep::view view(view_from_native(*view_info, server_state.id()));
358380
server_state.on_view(view, high_priority_service);
359381
return WSREP_CB_SUCCESS;
360382
}

0 commit comments

Comments
 (0)