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

Bootstrap server service, fixes to server state management

* Added bootstrap service call to do DBMS side bootstrap operations
  during the cluster bootstrap.
* Added last_committed_gtid() to provider interface
* Implemented wait_for_gtid() provider call
* Pass initial position to the server state
This commit is contained in:
Teemu Ollakka
2018-06-29 11:54:33 +03:00
parent 666eccf463
commit 0851970c53
15 changed files with 137 additions and 25 deletions

View File

@ -10,3 +10,14 @@ std::ostream& wsrep::operator<<(std::ostream& os, const wsrep::gtid& gtid)
{
return (os << gtid.id() << ":" << gtid.seqno());
}
std::istream& wsrep::operator>>(std::istream& is, wsrep::gtid& gtid)
{
std::string id_str;
std::getline(is, id_str, ':');
long long seq;
is >> seq;
gtid = wsrep::gtid(wsrep::id(id_str), wsrep::seqno(seq));
std::cout << "GTID: " << gtid << "\n";
return is;
}

View File

@ -43,6 +43,18 @@ namespace
return oss.str();
}
//
// This method is used to deal with historical burden of several
// ways to bootstrap the cluster. Bootstrap happens if
//
// * bootstrap option is given
// * cluster_address is "gcomm://" (Galera provider)
//
bool is_bootstrap(const std::string& cluster_address, bool bootstrap)
{
return (bootstrap || cluster_address == "gcomm://");
}
int apply_write_set(wsrep::server_state& server_state,
wsrep::client_state& client_state,
const wsrep::ws_handle& ws_handle,
@ -242,7 +254,10 @@ namespace
int wsrep::server_state::load_provider(const std::string& provider_spec,
const std::string& provider_options)
{
wsrep::log_info() << "Loading provider " << provider_spec;
wsrep::log_info() << "Loading provider "
<< provider_spec
<< "initial position: "
<< initial_position_;
provider_ = wsrep::provider::make_provider(
*this, provider_spec, provider_options);
return (provider_ ? 0 : 1);
@ -259,8 +274,10 @@ int wsrep::server_state::connect(const std::string& cluster_name,
const std::string& state_donor,
bool bootstrap)
{
bootstrap_ = is_bootstrap(cluster_address, bootstrap);
wsrep::log_info() << "Connecting with bootstrap option: " << bootstrap_;
return provider().connect(cluster_name, cluster_address, state_donor,
bootstrap);
bootstrap_);
}
int wsrep::server_state::disconnect()
@ -468,18 +485,11 @@ wsrep::gtid wsrep::server_state::last_committed_gtid() const
return last_committed_gtid_;
}
int wsrep::server_state::wait_for_gtid(const wsrep::gtid& gtid) const
enum wsrep::provider::status
wsrep::server_state::wait_for_gtid(const wsrep::gtid& gtid, int timeout)
const
{
wsrep::unique_lock<wsrep::mutex> lock(mutex_);
if (gtid.id() != last_committed_gtid_.id())
{
return 1;
}
while (last_committed_gtid_.seqno() < gtid.seqno())
{
cond_.wait(lock);
}
return 0;
return provider_->wait_for_gtid(gtid, timeout);
}
enum wsrep::provider::status
@ -522,8 +532,20 @@ void wsrep::server_state::on_view(const wsrep::view& view)
{
wsrep::unique_lock<wsrep::mutex> lock(mutex_);
assert(view.final() == false);
// Cluster was bootstrapped
if (state_ == s_connected && view.members().size() == 1)
//
// Reached primary from connected state. This may mean the following
//
// 1) Server was joined to the cluster and got SST transfer
// 2) Server was partitioned from the cluster and got back
// 3) A new cluster was bootstrapped from non-prim cluster
//
// There is no enough information here what was the cause
// of the primary component, so we need to walk through
// all states leading to joined to notify possible state
// waiters in other threads.
//
if (state_ == s_connected)
{
state(lock, s_joiner);
state(lock, s_initializing);
@ -531,12 +553,16 @@ void wsrep::server_state::on_view(const wsrep::view& view)
if (init_initialized_ == false)
{
// DBMS has not been initialized yet
wait_until_state(lock, s_initialized);
}
assert(init_initialized_);
if (bootstrap_)
{
server_service_.bootstrap();
bootstrap_ = false;
}
if (state_ == s_initialized)
{
state(lock, s_joined);

View File

@ -379,6 +379,8 @@ int wsrep::transaction::after_commit()
}
assert(ret == 0);
state(lock, s_committed);
// client_state_.server_state().last_committed_gtid(ws_meta.gitd());
debug_log_state("after_commit_leave");
return ret;
}
@ -550,7 +552,12 @@ int wsrep::transaction::after_statement()
if (ordered())
{
ret = provider().commit_order_enter(ws_handle_, ws_meta_);
if (ret == 0) provider().commit_order_leave(ws_handle_, ws_meta_);
if (ret == 0)
{
// client_state_.server_state().last_committed_gtid(
// ws_meta.gtid());
provider().commit_order_leave(ws_handle_, ws_meta_);
}
}
provider().release(ws_handle_);
}

View File

@ -465,6 +465,11 @@ wsrep::wsrep_provider_v26::wsrep_provider_v26(
: provider(server_state)
, wsrep_()
{
wsrep_gtid_t state_id;
std::memcpy(state_id.uuid.data,
server_state.initial_position().id().data(),
sizeof(state_id.uuid.data));
state_id.seqno = server_state.initial_position().seqno().get();
struct wsrep_init_args init_args;
memset(&init_args, 0, sizeof(init_args));
init_args.app_ctx = &server_state;
@ -474,7 +479,7 @@ wsrep::wsrep_provider_v26::wsrep_provider_v26(
init_args.data_dir = server_state_.working_dir().c_str();
init_args.options = provider_options.c_str();
init_args.proto_ver = server_state.max_protocol_version();
init_args.state_id = 0;
init_args.state_id = &state_id;
init_args.state = 0;
init_args.logger_cb = &logger_cb;
init_args.connected_cb = &connected_cb;
@ -704,6 +709,29 @@ wsrep::wsrep_provider_v26::causal_read(int timeout) const
return map_return_value(wsrep_->sync_wait(wsrep_, 0, timeout, 0));
}
enum wsrep::provider::status
wsrep::wsrep_provider_v26::wait_for_gtid(const wsrep::gtid& gtid, int timeout)
const
{
wsrep_gtid_t wsrep_gtid;
std::memcpy(wsrep_gtid.uuid.data, gtid.id().data(),
sizeof(wsrep_gtid.uuid.data));
wsrep_gtid.seqno = gtid.seqno().get();
return map_return_value(wsrep_->sync_wait(wsrep_, &wsrep_gtid, timeout, 0));
}
wsrep::gtid wsrep::wsrep_provider_v26::last_committed_gtid() const
{
wsrep_gtid_t wsrep_gtid;
if (wsrep_->last_committed_id(wsrep_, &wsrep_gtid) != WSREP_OK)
{
throw wsrep::runtime_error("Failed to read last committed id");
}
return wsrep::gtid(
wsrep::id(wsrep_gtid.uuid.data, sizeof(wsrep_gtid.uuid.data)),
wsrep::seqno(wsrep_gtid.seqno));
}
int wsrep::wsrep_provider_v26::sst_sent(const wsrep::gtid& gtid, int err)
{
wsrep_gtid_t wsrep_gtid;

View File

@ -57,7 +57,8 @@ namespace wsrep
int);
enum wsrep::provider::status leave_toi(wsrep::client_id);
enum wsrep::provider::status causal_read(int) const;
enum wsrep::provider::status wait_for_gtid(const wsrep::gtid&, int) const;
wsrep::gtid last_committed_gtid() const;
int sst_sent(const wsrep::gtid&,int);
int sst_received(const wsrep::gtid& gtid, int);