Commit 369c0267 authored by Nirbhay Choubey's avatar Nirbhay Choubey

MDEV-7053: WSREP_STATUS & WSREP_MEMBERSHIP I_S tables

wsrep_info INFORMATION_SCHEMA plugin to provide WSREP_STATUS
and WSREP_MEMBERSHIP tables.
parent cbc318fc
IF (WITH_WSREP)
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql
${CMAKE_SOURCE_DIR}/wsrep)
MYSQL_ADD_PLUGIN(WSREP_STATUS plugin.cc)
ENDIF()
# Use default setting for mysqld processes
!include include/default_mysqld.cnf
[mysqld]
wsrep-on=1
binlog-format=row
innodb-autoinc-lock-mode=2
innodb-locks-unsafe-for-binlog=1
wsrep-cluster-address=gcomm://
wsrep_provider=@ENV.WSREP_PROVIDER
# enforce read-committed characteristics across the cluster
wsrep_causal_reads=ON
[mysqld.1]
#galera_port=@OPT.port
#sst_port=@OPT.port
wsrep_provider_options='base_port=@mysqld.1.#galera_port'
wsrep_sst_receive_address='127.0.0.1:@mysqld.1.#sst_port'
wsrep_node_name=test-node-1
[mysqld.2]
#galera_port=@OPT.port
#sst_port=@OPT.port
wsrep_cluster_address='gcomm://127.0.0.1:@mysqld.1.#galera_port'
wsrep_provider_options='base_port=@mysqld.2.#galera_port'
wsrep_sst_receive_address='127.0.0.1:@mysqld.2.#sst_port'
wsrep_node_name=test-node-2
[ENV]
NODE_MYPORT_1= @mysqld.1.port
NODE_MYSOCK_1= @mysqld.1.socket
NODE_MYPORT_2= @mysqld.2.port
NODE_MYSOCK_2= @mysqld.2.socket
# On node 1
SELECT * FROM INFORMATION_SCHEMA.WSREP_STATUS;
NODE_INDEX NODE_STATUS CLUSTER_STATUS CLUSTER_SIZE CLUSTER_STATE_UUID CLUSTER_STATE_SEQNO CLUSTER_CONF_ID GAP PROTOCOL_VERSION
<IDX> Synced Primary 2 <CLUSTER_STATE_UUID> 0 2 NO 3
SELECT * FROM INFORMATION_SCHEMA.WSREP_MEMBERSHIP ORDER BY NAME;
INDEX UUID NAME ADDRESS
<IDX> <MEMBER_ID> test-node-1 <ADDRESS>
<IDX> <MEMBER_ID> test-node-2 <ADDRESS>
# On node 2
SELECT * FROM INFORMATION_SCHEMA.WSREP_STATUS;
NODE_INDEX NODE_STATUS CLUSTER_STATUS CLUSTER_SIZE CLUSTER_STATE_UUID CLUSTER_STATE_SEQNO CLUSTER_CONF_ID GAP PROTOCOL_VERSION
<IDX> Synced Primary 2 <CLUSTER_STATE_UUID> 0 2 YES 3
SELECT * FROM INFORMATION_SCHEMA.WSREP_MEMBERSHIP ORDER BY NAME;
INDEX UUID NAME ADDRESS
<IDX> <MEMBER_ID> test-node-1 <ADDRESS>
<IDX> <MEMBER_ID> test-node-2 <ADDRESS>
# End of test
--plugin-load-add=$WSREP_STATUS_SO
package My::Suite::WSREP_STATUS;
use File::Basename;
use My::Find;
@ISA = qw(My::Suite);
return "Not run for embedded server" if $::opt_embedded_server;
return "WSREP is not compiled in" unless defined $::mysqld_variables{'wsrep-on'};
my ($provider) = grep { -f $_ } $ENV{WSREP_PROVIDER},
"/usr/lib/galera/libgalera_smm.so",
"/usr/lib64/galera/libgalera_smm.so";
return "No wsrep provider library" unless -f $provider;
return "No WSREP_STATUS plugin" unless $ENV{WSREP_STATUS_SO};
$ENV{WSREP_PROVIDER} = $provider;
my ($spath) = grep { -f "$_/wsrep_sst_rsync"; } "$::bindir/scripts", $::path_client_bindir;
return "No SST scripts" unless $spath;
my ($epath) = grep { -f "$_/my_print_defaults"; } "$::bindir/extra", $::path_client_bindir;
return "No my_print_defaults" unless $epath;
push @::global_suppressions,
(
qr(WSREP:.*down context.*),
qr(WSREP: Failed to send state UUID:.*),
qr(WSREP: wsrep_sst_receive_address.*),
qr(WSREP: Could not open saved state file for reading: .*),
qr(WSREP: last inactive check more than .* skipping check),
qr(WSREP: Gap in state sequence. Need state transfer.),
qr(WSREP: Failed to prepare for incremental state transfer: .*),
);
$ENV{PATH}="$epath:$ENV{PATH}";
$ENV{PATH}="$spath:$ENV{PATH}" unless $epath eq $spath;
bless { };
--source include/galera_cluster.inc
--source include/have_innodb.inc
--echo # On node 1
--connection node_1
--replace_column 1 <IDX> 5 <CLUSTER_STATE_UUID>
SELECT * FROM INFORMATION_SCHEMA.WSREP_STATUS;
--replace_column 1 <IDX> 2 <MEMBER_ID> 4 <ADDRESS>
SELECT * FROM INFORMATION_SCHEMA.WSREP_MEMBERSHIP ORDER BY NAME;
--echo # On node 2
--connection node_2
--replace_column 1 <IDX> 5 <CLUSTER_STATE_UUID>
SELECT * FROM INFORMATION_SCHEMA.WSREP_STATUS;
--replace_column 1 <IDX> 2 <MEMBER_ID> 4 <ADDRESS>
SELECT * FROM INFORMATION_SCHEMA.WSREP_MEMBERSHIP ORDER BY NAME;
--source include/galera_end.inc
--echo # End of test
/* Copyright (C) 2014 MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef MYSQL_SERVER
#define MYSQL_SERVER
#endif
#include <mysql/plugin.h>
#include <table.h> /* ST_SCHEMA_TABLE */
#include <sql_show.h>
#include <sql_acl.h> /* check_global_access() */
#include <wsrep_mysqld.h>
#include <wsrep_utils.h>
/* WSREP_MEMBERSHIP table fields */
/* Node index */
#define COLUMN_WSREP_MEMB_INDEX 0
/* Unique member ID */
#define COLUMN_WSREP_MEMB_UUID 1
/* Human-readable name */
#define COLUMN_WSREP_MEMB_NAME 2
/* Incoming address */
#define COLUMN_WSREP_MEMB_ADDRESS 3
/* WSREP_STATUS table fields */
/* Node index */
#define COLUMN_WSREP_STATUS_NODE_INDEX 0
/* Node status */
#define COLUMN_WSREP_STATUS_NODE_STATUS 1
/* Cluster status */
#define COLUMN_WSREP_STATUS_CLUSTER_STATUS 2
/* Cluster size */
#define COLUMN_WSREP_STATUS_CLUSTER_SIZE 3
/* Global cluster state UUID */
#define COLUMN_WSREP_STATUS_CLUSTER_STATE_UUID 4
/* Global cluster state Sequence number */
#define COLUMN_WSREP_STATUS_CLUSTER_STATE_SEQNO 5
/* Cluster membership changes */
#define COLUMN_WSREP_STATUS_CLUSTER_CONF_ID 6
/* Gap between global and local states ? */
#define COLUMN_WSREP_STATUS_GAP 7
/* Application protocol version */
#define COLUMN_WSREP_STATUS_PROTO_VERSION 8
static const char* get_member_status(wsrep_member_status_t status)
{
switch (status)
{
case WSREP_MEMBER_UNDEFINED: return "Undefined";
case WSREP_MEMBER_JOINER: return "Joiner";
case WSREP_MEMBER_DONOR: return "Donor";
case WSREP_MEMBER_JOINED: return "Joined";
case WSREP_MEMBER_SYNCED: return "Synced";
case WSREP_MEMBER_ERROR: return "Error";
default: break;
}
return "UNKNOWN";
}
static const char* get_cluster_status(wsrep_view_status_t status)
{
switch (status)
{
case WSREP_VIEW_PRIMARY: return "Primary";
case WSREP_VIEW_NON_PRIMARY: return "Non-primary";
case WSREP_VIEW_DISCONNECTED: return "Disconnected";
default: break;
}
return "UNKNOWN";
}
static ST_FIELD_INFO wsrep_memb_fields[]=
{
{"INDEX", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Index", 0},
{"UUID", WSREP_UUID_STR_LEN, MYSQL_TYPE_STRING, 0, 0, "Uuid", 0},
{"NAME", WSREP_MEMBER_NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Name", 0},
{"ADDRESS", WSREP_INCOMING_LEN, MYSQL_TYPE_STRING, 0, 0, "Address", 0},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0}
};
static ST_FIELD_INFO wsrep_status_fields[]=
{
{"NODE_INDEX", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG,
0, 0, "Node_Index", 0},
{"NODE_STATUS", 16, MYSQL_TYPE_STRING, 0, 0, "Node_Status", 0},
{"CLUSTER_STATUS", 16, MYSQL_TYPE_STRING, 0, 0, "Cluster_Status", 0},
{"CLUSTER_SIZE", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG,
0, 0, "Cluster_Size", 0},
{"CLUSTER_STATE_UUID", WSREP_UUID_STR_LEN, MYSQL_TYPE_STRING,
0, 0, 0, 0},
{"CLUSTER_STATE_SEQNO", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
0, 0, 0, 0},
{"CLUSTER_CONF_ID", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
0, 0, 0, 0},
{"GAP", 10, MYSQL_TYPE_STRING, 0, 0, 0, 0},
{"PROTOCOL_VERSION", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG,
0, 0, 0, 0},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0}
};
static int wsrep_memb_fill_table(THD *thd, TABLE_LIST *tables, COND *cond)
{
int rc= 0;
if (check_global_access(thd, SUPER_ACL, true))
return rc;
wsrep_config_state.lock();
Dynamic_array<wsrep_member_info_t> *memb_arr=
wsrep_config_state.get_member_info();
TABLE *table= tables->table;
for (unsigned int i= 0; i < memb_arr->elements(); i ++)
{
wsrep_member_info_t memb= memb_arr->at(i);
table->field[COLUMN_WSREP_MEMB_INDEX]->store(i, 0);
char uuid[40];
wsrep_uuid_print(&memb.id, uuid, sizeof(uuid));
table->field[COLUMN_WSREP_MEMB_UUID]->store(uuid, sizeof(uuid),
system_charset_info);
table->field[COLUMN_WSREP_MEMB_NAME]->store(memb.name, strlen(memb.name),
system_charset_info);
table->field[COLUMN_WSREP_MEMB_ADDRESS]->store(memb.incoming,
strlen(memb.incoming),
system_charset_info);
if (schema_table_store_record(thd, table))
{
rc= 1;
goto end;
}
}
end:
wsrep_config_state.unlock();
return rc;
}
static int wsrep_memb_plugin_init(void *p)
{
ST_SCHEMA_TABLE *schema= (ST_SCHEMA_TABLE *)p;
schema->fields_info= wsrep_memb_fields;
schema->fill_table= wsrep_memb_fill_table;
return 0;
}
static struct st_mysql_information_schema wsrep_memb_plugin=
{ MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION };
static int wsrep_status_fill_table(THD *thd, TABLE_LIST *tables, COND *cond)
{
int rc= 0;
if (check_global_access(thd, SUPER_ACL, true))
return rc;
wsrep_config_state.lock();
wsrep_view_info_t view= wsrep_config_state.get_view_info();
wsrep_member_status_t status= wsrep_config_state.get_status();
TABLE *table= tables->table;
table->field[COLUMN_WSREP_STATUS_NODE_INDEX]
->store(view.my_idx, 0);
table->field[COLUMN_WSREP_STATUS_NODE_STATUS]
->store(get_member_status(status), strlen(get_member_status(status)),
system_charset_info);
table->field[COLUMN_WSREP_STATUS_CLUSTER_STATUS]
->store(get_cluster_status(view.status),
strlen(get_cluster_status(view.status)),
system_charset_info);
table->field[COLUMN_WSREP_STATUS_CLUSTER_SIZE]->store(view.memb_num, 0);
char uuid[40];
wsrep_uuid_print(&view.state_id.uuid, uuid, sizeof(uuid));
table->field[COLUMN_WSREP_STATUS_CLUSTER_STATE_UUID]
->store(uuid, sizeof(uuid), system_charset_info);
table->field[COLUMN_WSREP_STATUS_CLUSTER_STATE_SEQNO]
->store(view.state_id.seqno, 0);
table->field[COLUMN_WSREP_STATUS_CLUSTER_CONF_ID]->store(view.view, 0);
const char *gap= (view.state_gap == true) ? "YES" : "NO";
table->field[COLUMN_WSREP_STATUS_GAP]->store(gap, strlen(gap),
system_charset_info);
table->field[COLUMN_WSREP_STATUS_PROTO_VERSION]->store(view.proto_ver, 0);
if (schema_table_store_record(thd, table))
rc= 1;
wsrep_config_state.unlock();
return rc;
}
static int wsrep_status_plugin_init(void *p)
{
ST_SCHEMA_TABLE *schema= (ST_SCHEMA_TABLE *)p;
schema->fields_info= wsrep_status_fields;
schema->fill_table= wsrep_status_fill_table;
return 0;
}
static struct st_mysql_information_schema wsrep_status_plugin=
{ MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION };
/*
Plugin library descriptor
*/
maria_declare_plugin(wsrep_status)
{
MYSQL_INFORMATION_SCHEMA_PLUGIN,
&wsrep_memb_plugin,
"WSREP_MEMBERSHIP", /* Plugin name */
"Nirbhay Choubey", /* Plugin author */
"Information about group members", /* Plugin description */
PLUGIN_LICENSE_GPL, /* License */
wsrep_memb_plugin_init, /* Plugin Init */
0, /* Plugin Deinit */
0x0100, /* Version (hex) */
NULL, /* Status variables */
NULL, /* System variables */
"1.0", /* Version (string) */
MariaDB_PLUGIN_MATURITY_ALPHA /* Maturity */
},
{
MYSQL_INFORMATION_SCHEMA_PLUGIN,
&wsrep_status_plugin,
"WSREP_STATUS", /* Plugin name */
"Nirbhay Choubey", /* Plugin author */
"Group view information", /* Plugin description */
PLUGIN_LICENSE_GPL, /* License */
wsrep_status_plugin_init, /* Plugin Init */
0, /* Plugin Deinit */
0x0100, /* Version (hex) */
NULL, /* Status variables */
NULL, /* System variables */
"1.0", /* Version (string) */
MariaDB_PLUGIN_MATURITY_ALPHA /* Maturity */
}
maria_declare_plugin_end;
......@@ -110,6 +110,8 @@ mysql_mutex_t LOCK_wsrep_replaying;
mysql_cond_t COND_wsrep_replaying;
mysql_mutex_t LOCK_wsrep_slave_threads;
mysql_mutex_t LOCK_wsrep_desync;
mysql_mutex_t LOCK_wsrep_config_state;
int wsrep_replaying= 0;
ulong wsrep_running_threads = 0; // # of currently running wsrep threads
ulong my_bind_addr;
......@@ -118,7 +120,8 @@ ulong my_bind_addr;
PSI_mutex_key key_LOCK_wsrep_rollback, key_LOCK_wsrep_thd,
key_LOCK_wsrep_replaying, key_LOCK_wsrep_ready, key_LOCK_wsrep_sst,
key_LOCK_wsrep_sst_thread, key_LOCK_wsrep_sst_init,
key_LOCK_wsrep_slave_threads, key_LOCK_wsrep_desync;
key_LOCK_wsrep_slave_threads, key_LOCK_wsrep_desync,
key_LOCK_wsrep_config_state;
PSI_cond_key key_COND_wsrep_rollback, key_COND_wsrep_thd,
key_COND_wsrep_replaying, key_COND_wsrep_ready, key_COND_wsrep_sst,
......@@ -135,7 +138,8 @@ static PSI_mutex_info wsrep_mutexes[]=
{ &key_LOCK_wsrep_thd, "THD::LOCK_wsrep_thd", 0},
{ &key_LOCK_wsrep_replaying, "LOCK_wsrep_replaying", PSI_FLAG_GLOBAL},
{ &key_LOCK_wsrep_slave_threads, "LOCK_wsrep_slave_threads", PSI_FLAG_GLOBAL},
{ &key_LOCK_wsrep_desync, "LOCK_wsrep_desync", PSI_FLAG_GLOBAL}
{ &key_LOCK_wsrep_desync, "LOCK_wsrep_desync", PSI_FLAG_GLOBAL},
{ &key_LOCK_wsrep_config_state, "LOCK_wsrep_config_state", PSI_FLAG_GLOBAL}
};
static PSI_cond_info wsrep_conds[]=
......@@ -186,9 +190,10 @@ const char* wsrep_provider_vendor = provider_vendor;
wsrep_uuid_t local_uuid = WSREP_UUID_UNDEFINED;
wsrep_seqno_t local_seqno = WSREP_SEQNO_UNDEFINED;
wsp::node_status local_status;
long wsrep_protocol_version = 3;
wsp::Config_state wsrep_config_state;
// Boolean denoting if server is in initial startup phase. This is needed
// to make sure that main thread waiting in wsrep_sst_wait() is signaled
// if there was no state gap on receiving first view event.
......@@ -306,7 +311,7 @@ wsrep_view_handler_cb (void* app_ctx,
*sst_req = NULL;
*sst_req_len = 0;
wsrep_member_status_t new_status= local_status.get();
wsrep_member_status_t memb_status= wsrep_config_state.get_status();
if (memcmp(&cluster_uuid, &view->state_id.uuid, sizeof(wsrep_uuid_t)))
{
......@@ -331,7 +336,7 @@ wsrep_view_handler_cb (void* app_ctx,
/* Proceed further only if view is PRIMARY */
if (WSREP_VIEW_PRIMARY != view->status) {
wsrep_ready_set(FALSE);
new_status= WSREP_MEMBER_UNDEFINED;
memb_status= WSREP_MEMBER_UNDEFINED;
/* Always record local_uuid and local_seqno in non-prim since this
* may lead to re-initializing provider and start position is
* determined according to these variables */
......@@ -386,13 +391,13 @@ wsrep_view_handler_cb (void* app_ctx,
{
WSREP_ERROR("SST preparation failed: %zd (%s)", -req_len,
strerror(-req_len));
new_status= WSREP_MEMBER_UNDEFINED;
memb_status= WSREP_MEMBER_UNDEFINED;
}
else
{
assert(sst_req != NULL);
*sst_req_len= req_len;
new_status= WSREP_MEMBER_JOINER;
memb_status= WSREP_MEMBER_JOINER;
}
}
else
......@@ -420,7 +425,7 @@ wsrep_view_handler_cb (void* app_ctx,
XID xid;
wsrep_xid_init(&xid, &local_uuid, local_seqno);
wsrep_set_SE_checkpoint(&xid);
new_status= WSREP_MEMBER_JOINED;
memb_status= WSREP_MEMBER_JOINED;
#ifdef GTID_SUPPORT
wsrep_init_sidno(local_uuid);
#endif /* GTID_SUPPORT */
......@@ -456,7 +461,7 @@ wsrep_view_handler_cb (void* app_ctx,
out:
if (view->status == WSREP_VIEW_PRIMARY) wsrep_startup= FALSE;
local_status.set(new_status, view);
wsrep_config_state.set(memb_status, view);
return WSREP_CB_SUCCESS;
}
......@@ -498,7 +503,7 @@ static void wsrep_synced_cb(void* app_ctx)
signal_main= true;
}
local_status.set(WSREP_MEMBER_SYNCED);
wsrep_config_state.set(WSREP_MEMBER_SYNCED);
mysql_mutex_unlock (&LOCK_wsrep_ready);
if (signal_main)
......@@ -601,6 +606,7 @@ int wsrep_init()
mysql_cond_init(key_COND_wsrep_replaying, &COND_wsrep_replaying, NULL);
mysql_mutex_init(key_LOCK_wsrep_slave_threads, &LOCK_wsrep_slave_threads, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_LOCK_wsrep_desync, &LOCK_wsrep_desync, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_LOCK_wsrep_config_state, &LOCK_wsrep_config_state, MY_MUTEX_INIT_FAST);
wsrep_ready_set(FALSE);
assert(wsrep_provider);
......@@ -846,6 +852,7 @@ void wsrep_deinit(bool free_options)
mysql_cond_destroy(&COND_wsrep_replaying);
mysql_mutex_destroy(&LOCK_wsrep_slave_threads);
mysql_mutex_destroy(&LOCK_wsrep_desync);
mysql_mutex_destroy(&LOCK_wsrep_config_state);
}
void wsrep_recover()
......
......@@ -232,6 +232,7 @@ extern mysql_mutex_t LOCK_wsrep_replaying;
extern mysql_cond_t COND_wsrep_replaying;
extern mysql_mutex_t LOCK_wsrep_slave_threads;
extern mysql_mutex_t LOCK_wsrep_desync;
extern mysql_mutex_t LOCK_wsrep_config_state;
extern wsrep_aborting_thd_t wsrep_aborting_thd;
extern my_bool wsrep_emulate_bin_log;
extern int wsrep_to_isolation;
......
......@@ -1102,8 +1102,8 @@ wsrep_cb_status_t wsrep_sst_donate_cb (void* app_ctx, void* recv_ctx,
{
/* This will be reset when sync callback is called.
* Should we set wsrep_ready to FALSE here too? */
// wsrep_notify_status(WSREP_MEMBER_DONOR);
local_status.set(WSREP_MEMBER_DONOR);
wsrep_config_state.set(WSREP_MEMBER_DONOR);
const char* method = (char*)msg;
size_t method_len = strlen (method);
......
......@@ -17,32 +17,82 @@
#define WSREP_UTILS_H
#include "wsrep_priv.h"
#include "wsrep_mysqld.h"
unsigned int wsrep_check_ip (const char* addr);
size_t wsrep_guess_ip (char* buf, size_t buf_len);
size_t wsrep_guess_address(char* buf, size_t buf_len);
namespace wsp {
class node_status
class Config_state
{
public:
node_status() : status(WSREP_MEMBER_UNDEFINED) {}
void set(wsrep_member_status_t new_status,
const wsrep_view_info_t* view = 0)
Config_state() : view_(), status_(WSREP_MEMBER_UNDEFINED)
{}
void set(wsrep_member_status_t status, const wsrep_view_info_t* view)
{
wsrep_notify_status(status, view);
lock();
status_= status;
view_= *view;
member_info_.clear();
wsrep_member_info_t memb;
for(int i= 0; i < view->memb_num; i ++)
{
memb= view->members[i];
member_info_.append_val(memb);
}
unlock();
}
void set(wsrep_member_status_t status)
{
wsrep_notify_status(status, 0);
lock();
status_= status;
unlock();
}
wsrep_view_info_t get_view_info() const
{
if (status != new_status || 0 != view)
return view_;
}
wsrep_member_status_t get_status() const
{
wsrep_notify_status(new_status, view);
status = new_status;
return status_;
}
Dynamic_array<wsrep_member_info_t> * get_member_info()
{
return &member_info_;
}
wsrep_member_status_t get() const { return status; }
int lock()
{
return mysql_mutex_lock(&LOCK_wsrep_config_state);
}
int unlock()
{
return mysql_mutex_unlock(&LOCK_wsrep_config_state);
}
private:
wsrep_member_status_t status;
wsrep_view_info_t view_;
wsrep_member_status_t status_;
Dynamic_array<wsrep_member_info_t> member_info_;
};
} /* namespace wsp */
extern wsp::node_status local_status;
extern wsp::Config_state wsrep_config_state;
namespace wsp {
/* A small class to run external programs. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment