MXS-1775 Turn Galera monitor into a class.

A mechanical change, without any functional modifications.
This commit is contained in:
Johan Wikman
2018-05-15 19:30:04 +03:00
parent cd233fe594
commit 4b236a79db
2 changed files with 205 additions and 208 deletions

View File

@ -25,34 +25,17 @@
#define DONOR_NODE_NAME_MAX_LEN 60 #define DONOR_NODE_NAME_MAX_LEN 60
#define DONOR_LIST_SET_VAR "SET GLOBAL wsrep_sst_donor = \"" #define DONOR_LIST_SET_VAR "SET GLOBAL wsrep_sst_donor = \""
static void monitorMain(void *);
/** Log a warning when a bad 'wsrep_local_index' is found */ /** Log a warning when a bad 'wsrep_local_index' is found */
static bool warn_erange_on_local_index = true; static bool warn_erange_on_local_index = true;
static MXS_MONITOR_INSTANCE *createInstance(MXS_MONITOR *mon);
static void destroyInstance(MXS_MONITOR_INSTANCE* monitor);
static bool startMonitor(MXS_MONITOR_INSTANCE *,
const MXS_CONFIG_PARAMETER *params);
static void stopMonitor(MXS_MONITOR_INSTANCE *);
static void diagnostics(const MXS_MONITOR_INSTANCE *, DCB *);
static json_t* diagnostics_json(const MXS_MONITOR_INSTANCE *);
static MXS_MONITORED_SERVER *get_candidate_master(MXS_MONITOR*);
static MXS_MONITORED_SERVER *set_cluster_master(MXS_MONITORED_SERVER *, MXS_MONITORED_SERVER *, int); static MXS_MONITORED_SERVER *set_cluster_master(MXS_MONITORED_SERVER *, MXS_MONITORED_SERVER *, int);
static void disableMasterFailback(void *, int); static void disableMasterFailback(void *, int);
bool isGaleraEvent(mxs_monitor_event_t event); bool isGaleraEvent(mxs_monitor_event_t event);
static void update_sst_donor_nodes(MXS_MONITOR*, int);
static int compare_node_index(const void*, const void*); static int compare_node_index(const void*, const void*);
static int compare_node_priority(const void*, const void*); static int compare_node_priority(const void*, const void*);
static void reset_cluster_info(GALERA_MONITOR *);
static GALERA_NODE_INFO *nodeval_dup(const GALERA_NODE_INFO *); static GALERA_NODE_INFO *nodeval_dup(const GALERA_NODE_INFO *);
static void nodeval_free(GALERA_NODE_INFO *); static void nodeval_free(GALERA_NODE_INFO *);
static void set_galera_cluster(MXS_MONITOR *);
static bool detect_cluster_size(const GALERA_MONITOR *, const int, const char *, const int);
static void set_cluster_members(MXS_MONITOR *);
extern "C"
{
/** /**
* The module entry point routine. It is this routine that * The module entry point routine. It is this routine that
* must populate the structure that is referred to as the * must populate the structure that is referred to as the
@ -61,20 +44,10 @@ extern "C"
* *
* @return The module object * @return The module object
*/ */
MXS_MODULE* MXS_CREATE_MODULE() extern "C" MXS_MODULE* MXS_CREATE_MODULE()
{ {
MXS_NOTICE("Initialise the MySQL Galera Monitor module."); MXS_NOTICE("Initialise the MySQL Galera Monitor module.");
static MXS_MONITOR_API MyObject =
{
createInstance,
destroyInstance,
startMonitor,
stopMonitor,
diagnostics,
diagnostics_json
};
static MXS_MODULE info = static MXS_MODULE info =
{ {
MXS_MODULE_API_MONITOR, MXS_MODULE_API_MONITOR,
@ -83,7 +56,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
"A Galera cluster monitor", "A Galera cluster monitor",
"V2.0.0", "V2.0.0",
MXS_NO_MODULE_CAPABILITIES, MXS_NO_MODULE_CAPABILITIES,
&MyObject, &maxscale::MonitorApi<GaleraMonitor>::s_api,
NULL, /* Process init. */ NULL, /* Process init. */
NULL, /* Process finish. */ NULL, /* Process finish. */
NULL, /* Thread init. */ NULL, /* Thread init. */
@ -115,50 +88,60 @@ MXS_MODULE* MXS_CREATE_MODULE()
return &info; return &info;
} }
}
static MXS_MONITOR_INSTANCE *createInstance(MXS_MONITOR *mon) GaleraMonitor::GaleraMonitor(MXS_MONITOR *mon)
: m_thread(0)
, m_shutdown(0)
, m_status(0)
, m_id(MXS_MONITOR_DEFAULT_ID)
, m_disableMasterFailback(0)
, m_availableWhenDonor(0)
, m_disableMasterRoleSetting(0)
, m_master(NULL)
, m_script(NULL)
, m_root_node_as_master(false)
, m_use_priority(false)
, m_events(0)
, m_set_donor_nodes(false)
, m_galera_nodes_info(NULL)
, m_monitor(mon)
, m_checked(false)
{ {
GALERA_MONITOR* handle = static_cast<GALERA_MONITOR*>(MXS_CALLOC(1, sizeof(GALERA_MONITOR)));
HASHTABLE *nodes_info = hashtable_alloc(MAX_NUM_SLAVES, HASHTABLE *nodes_info = hashtable_alloc(MAX_NUM_SLAVES,
hashtable_item_strhash, hashtable_item_strhash,
hashtable_item_strcmp); hashtable_item_strcmp);
ss_dassert(nodes_info);
if (handle && nodes_info) if (!nodes_info)
{ {
hashtable_memory_fns(nodes_info, throw std::bad_alloc();
hashtable_item_strdup,
(HASHCOPYFN)nodeval_dup,
hashtable_item_free,
(HASHFREEFN)nodeval_free);
handle->shutdown = 0;
handle->id = MXS_MONITOR_DEFAULT_ID;
handle->master = NULL;
/* Initialise cluster nodes hash and Cluster info */
handle->galera_nodes_info = nodes_info;
handle->cluster_info.c_size = 0;
handle->cluster_info.c_uuid = NULL;
handle->monitor = mon;
handle->checked = false;
}
else
{
hashtable_free(nodes_info);
MXS_FREE(handle);
} }
return handle; hashtable_memory_fns(nodes_info,
hashtable_item_strdup,
(HASHCOPYFN)nodeval_dup,
hashtable_item_free,
(HASHFREEFN)nodeval_free);
m_galera_nodes_info = nodes_info;
m_cluster_info.c_size = 0;
m_cluster_info.c_uuid = NULL;
} }
static void destroyInstance(MXS_MONITOR_INSTANCE* monitor) GaleraMonitor::~GaleraMonitor()
{ {
GALERA_MONITOR* handle = static_cast<GALERA_MONITOR*>(monitor); hashtable_free(m_galera_nodes_info);
MXS_FREE(m_script);
}
hashtable_free(handle->galera_nodes_info); // static
MXS_FREE(handle->script); GaleraMonitor* GaleraMonitor::create(MXS_MONITOR* monitor)
MXS_FREE(handle); {
return new GaleraMonitor(monitor);
}
void GaleraMonitor::destroy()
{
delete this;
} }
/** /**
@ -168,45 +151,43 @@ static void destroyInstance(MXS_MONITOR_INSTANCE* monitor)
* *
* @return A handle to use when interacting with the monitor * @return A handle to use when interacting with the monitor
*/ */
static bool startMonitor(MXS_MONITOR_INSTANCE *mon, const MXS_CONFIG_PARAMETER *params) bool GaleraMonitor::start(const MXS_CONFIG_PARAMETER *params)
{ {
bool started = false; bool started = false;
GALERA_MONITOR *handle = static_cast<GALERA_MONITOR*>(mon); ss_dassert(!m_shutdown);
ss_dassert(!m_thread);
ss_dassert(!m_script);
ss_dassert(!handle->shutdown); if (!m_checked)
ss_dassert(!handle->thread);
ss_dassert(!handle->script);
if (!handle->checked)
{ {
if (!check_monitor_permissions(handle->monitor, "SHOW STATUS LIKE 'wsrep_local_state'")) if (!check_monitor_permissions(m_monitor, "SHOW STATUS LIKE 'wsrep_local_state'"))
{ {
MXS_ERROR("Failed to start monitor. See earlier errors for more information."); MXS_ERROR("Failed to start monitor. See earlier errors for more information.");
} }
else else
{ {
handle->checked = true; m_checked = true;
} }
} }
if (handle->checked) if (m_checked)
{ {
handle->disableMasterFailback = config_get_bool(params, "disable_master_failback"); m_disableMasterFailback = config_get_bool(params, "disable_master_failback");
handle->availableWhenDonor = config_get_bool(params, "available_when_donor"); m_availableWhenDonor = config_get_bool(params, "available_when_donor");
handle->disableMasterRoleSetting = config_get_bool(params, "disable_master_role_setting"); m_disableMasterRoleSetting = config_get_bool(params, "disable_master_role_setting");
handle->root_node_as_master = config_get_bool(params, "root_node_as_master"); m_root_node_as_master = config_get_bool(params, "root_node_as_master");
handle->use_priority = config_get_bool(params, "use_priority"); m_use_priority = config_get_bool(params, "use_priority");
handle->script = config_copy_string(params, "script"); m_script = config_copy_string(params, "script");
handle->events = config_get_enum(params, "events", mxs_monitor_event_enum_values); m_events = config_get_enum(params, "events", mxs_monitor_event_enum_values);
handle->set_donor_nodes = config_get_bool(params, "set_donor_nodes"); m_set_donor_nodes = config_get_bool(params, "set_donor_nodes");
/* Reset all data in the hashtable */ /* Reset all data in the hashtable */
reset_cluster_info(handle); reset_cluster_info();
if (thread_start(&handle->thread, monitorMain, handle, 0) == NULL) if (thread_start(&m_thread, &GaleraMonitor::main, this, 0) == NULL)
{ {
MXS_ERROR("Failed to start monitor thread for monitor '%s'.", handle->monitor->name); MXS_ERROR("Failed to start monitor thread for monitor '%s'.", m_monitor->name);
} }
else else
{ {
@ -222,19 +203,17 @@ static bool startMonitor(MXS_MONITOR_INSTANCE *mon, const MXS_CONFIG_PARAMETER *
* *
* @param arg Handle on thr running monior * @param arg Handle on thr running monior
*/ */
static void void GaleraMonitor::stop()
stopMonitor(MXS_MONITOR_INSTANCE *mon)
{ {
GALERA_MONITOR *handle = static_cast<GALERA_MONITOR*>(mon); ss_dassert(m_thread);
ss_dassert(handle->thread);
handle->shutdown = true; m_shutdown = true;
thread_wait(handle->thread); thread_wait(m_thread);
handle->thread = 0; m_thread = 0;
handle->shutdown = false; m_shutdown = false;
MXS_FREE(handle->script); MXS_FREE(m_script);
handle->script = NULL; m_script = NULL;
} }
/** /**
@ -243,20 +222,17 @@ stopMonitor(MXS_MONITOR_INSTANCE *mon)
* @param dcb DCB to send output * @param dcb DCB to send output
* @param arg The monitor handle * @param arg The monitor handle
*/ */
static void void GaleraMonitor::diagnostics(DCB *dcb) const
diagnostics(const MXS_MONITOR_INSTANCE *mon, DCB *dcb)
{ {
const GALERA_MONITOR *handle = static_cast<const GALERA_MONITOR*>(mon); dcb_printf(dcb, "Master Failback:\t%s\n", (m_disableMasterFailback == 1) ? "off" : "on");
dcb_printf(dcb, "Available when Donor:\t%s\n", (m_availableWhenDonor == 1) ? "on" : "off");
dcb_printf(dcb, "Master Failback:\t%s\n", (handle->disableMasterFailback == 1) ? "off" : "on");
dcb_printf(dcb, "Available when Donor:\t%s\n", (handle->availableWhenDonor == 1) ? "on" : "off");
dcb_printf(dcb, "Master Role Setting Disabled:\t%s\n", dcb_printf(dcb, "Master Role Setting Disabled:\t%s\n",
handle->disableMasterRoleSetting ? "on" : "off"); m_disableMasterRoleSetting ? "on" : "off");
dcb_printf(dcb, "Set wsrep_sst_donor node list:\t%s\n", (handle->set_donor_nodes == 1) ? "on" : "off"); dcb_printf(dcb, "Set wsrep_sst_donor node list:\t%s\n", (m_set_donor_nodes == 1) ? "on" : "off");
if (handle->cluster_info.c_uuid) if (m_cluster_info.c_uuid)
{ {
dcb_printf(dcb, "Galera Cluster UUID:\t%s\n", handle->cluster_info.c_uuid); dcb_printf(dcb, "Galera Cluster UUID:\t%s\n", m_cluster_info.c_uuid);
dcb_printf(dcb, "Galera Cluster size:\t%d\n", handle->cluster_info.c_size); dcb_printf(dcb, "Galera Cluster size:\t%d\n", m_cluster_info.c_size);
} }
else else
{ {
@ -269,26 +245,24 @@ diagnostics(const MXS_MONITOR_INSTANCE *mon, DCB *dcb)
* *
* @param arg The monitor handle * @param arg The monitor handle
*/ */
static json_t* diagnostics_json(const MXS_MONITOR_INSTANCE *mon) json_t* GaleraMonitor::diagnostics_json() const
{ {
json_t* rval = json_object(); json_t* rval = json_object();
const GALERA_MONITOR *handle = static_cast<const GALERA_MONITOR*>(mon); json_object_set_new(rval, "disable_master_failback", json_boolean(m_disableMasterFailback));
json_object_set_new(rval, "disable_master_role_setting", json_boolean(m_disableMasterRoleSetting));
json_object_set_new(rval, "root_node_as_master", json_boolean(m_root_node_as_master));
json_object_set_new(rval, "use_priority", json_boolean(m_use_priority));
json_object_set_new(rval, "set_donor_nodes", json_boolean(m_set_donor_nodes));
json_object_set_new(rval, "disable_master_failback", json_boolean(handle->disableMasterFailback)); if (m_script)
json_object_set_new(rval, "disable_master_role_setting", json_boolean(handle->disableMasterRoleSetting));
json_object_set_new(rval, "root_node_as_master", json_boolean(handle->root_node_as_master));
json_object_set_new(rval, "use_priority", json_boolean(handle->use_priority));
json_object_set_new(rval, "set_donor_nodes", json_boolean(handle->set_donor_nodes));
if (handle->script)
{ {
json_object_set_new(rval, "script", json_string(handle->script)); json_object_set_new(rval, "script", json_string(m_script));
} }
if (handle->cluster_info.c_uuid) if (m_cluster_info.c_uuid)
{ {
json_object_set_new(rval, "cluster_uuid", json_string(handle->cluster_info.c_uuid)); json_object_set_new(rval, "cluster_uuid", json_string(m_cluster_info.c_uuid));
json_object_set_new(rval, "cluster_size", json_integer(handle->cluster_info.c_size)); json_object_set_new(rval, "cluster_size", json_integer(m_cluster_info.c_size));
} }
return rval; return rval;
@ -337,10 +311,8 @@ static bool using_xtrabackup(MXS_MONITORED_SERVER *database, const char* server_
* @param handle The MySQL Monitor object * @param handle The MySQL Monitor object
* @param database The database to probe * @param database The database to probe
*/ */
static void void GaleraMonitor::monitorDatabase(MXS_MONITORED_SERVER *database)
monitorDatabase(MXS_MONITOR *mon, MXS_MONITORED_SERVER *database)
{ {
GALERA_MONITOR* handle = static_cast<GALERA_MONITOR*>(mon->instance);
MYSQL_ROW row; MYSQL_ROW row;
MYSQL_RES *result; MYSQL_RES *result;
char *server_string; char *server_string;
@ -354,7 +326,7 @@ monitorDatabase(MXS_MONITOR *mon, MXS_MONITORED_SERVER *database)
/** Store previous status */ /** Store previous status */
database->mon_prev_status = database->server->status; database->mon_prev_status = database->server->status;
mxs_connect_result_t rval = mon_ping_or_connect_to_db(mon, database); mxs_connect_result_t rval = mon_ping_or_connect_to_db(m_monitor, database);
if (!mon_connection_is_ok(rval)) if (!mon_connection_is_ok(rval))
{ {
if (mysql_errno(database->con) == ER_ACCESS_DENIED_ERROR) if (mysql_errno(database->con) == ER_ACCESS_DENIED_ERROR)
@ -442,7 +414,7 @@ monitorDatabase(MXS_MONITOR *mon, MXS_MONITORED_SERVER *database)
info.joined = 1; info.joined = 1;
} }
/* Check if the node is a donor and is using xtrabackup, in this case it can stay alive */ /* Check if the node is a donor and is using xtrabackup, in this case it can stay alive */
else if (strcmp(row[1], "2") == 0 && handle->availableWhenDonor == 1 && else if (strcmp(row[1], "2") == 0 && m_availableWhenDonor == 1 &&
using_xtrabackup(database, server_string)) using_xtrabackup(database, server_string))
{ {
info.joined = 1; info.joined = 1;
@ -483,7 +455,7 @@ monitorDatabase(MXS_MONITOR *mon, MXS_MONITORED_SERVER *database)
info.node = database->server; info.node = database->server;
/* Galera Cluster vars fetch */ /* Galera Cluster vars fetch */
HASHTABLE *table = handle->galera_nodes_info; HASHTABLE *table = m_galera_nodes_info;
GALERA_NODE_INFO *node = GALERA_NODE_INFO *node =
static_cast<GALERA_NODE_INFO*>(hashtable_fetch(table, database->server->name)); static_cast<GALERA_NODE_INFO*>(hashtable_fetch(table, database->server->name));
if (node) if (node)
@ -527,11 +499,14 @@ monitorDatabase(MXS_MONITOR *mon, MXS_MONITORED_SERVER *database)
* *
* @param arg The handle of the monitor * @param arg The handle of the monitor
*/ */
static void //static
monitorMain(void *arg) void GaleraMonitor::main(void* arg)
{
return static_cast<GaleraMonitor*>(arg)->main();
}
void GaleraMonitor::main()
{ {
GALERA_MONITOR *handle = (GALERA_MONITOR*)arg;
MXS_MONITOR* mon = handle->monitor;
MXS_MONITORED_SERVER *ptr; MXS_MONITORED_SERVER *ptr;
size_t nrounds = 0; size_t nrounds = 0;
MXS_MONITORED_SERVER *candidate_master = NULL; MXS_MONITORED_SERVER *candidate_master = NULL;
@ -539,22 +514,22 @@ monitorMain(void *arg)
int is_cluster = 0; int is_cluster = 0;
int log_no_members = 1; int log_no_members = 1;
master_stickiness = handle->disableMasterFailback; master_stickiness = m_disableMasterFailback;
if (mysql_thread_init()) if (mysql_thread_init())
{ {
MXS_ERROR("mysql_thread_init failed in monitor module. Exiting."); MXS_ERROR("mysql_thread_init failed in monitor module. Exiting.");
return; return;
} }
handle->status = MXS_MONITOR_RUNNING; m_status = MXS_MONITOR_RUNNING;
load_server_journal(mon, NULL); load_server_journal(m_monitor, NULL);
while (1) while (1)
{ {
if (handle->shutdown) if (m_shutdown)
{ {
handle->status = MXS_MONITOR_STOPPING; m_status = MXS_MONITOR_STOPPING;
mysql_thread_end(); mysql_thread_end();
handle->status = MXS_MONITOR_STOPPED; m_status = MXS_MONITOR_STOPPED;
return; return;
} }
@ -568,8 +543,8 @@ monitorMain(void *arg)
* round. * round.
*/ */
if (nrounds != 0 && if (nrounds != 0 &&
(((nrounds * MXS_MON_BASE_INTERVAL_MS) % mon->interval) >= (((nrounds * MXS_MON_BASE_INTERVAL_MS) % m_monitor->interval) >=
MXS_MON_BASE_INTERVAL_MS) && (!mon->server_pending_changes)) MXS_MON_BASE_INTERVAL_MS) && (!m_monitor->server_pending_changes))
{ {
nrounds += 1; nrounds += 1;
continue; continue;
@ -580,15 +555,15 @@ monitorMain(void *arg)
/* reset cluster members counter */ /* reset cluster members counter */
is_cluster = 0; is_cluster = 0;
lock_monitor_servers(mon); lock_monitor_servers(m_monitor);
servers_status_pending_to_current(mon); servers_status_pending_to_current(m_monitor);
ptr = mon->monitored_servers; ptr = m_monitor->monitored_servers;
while (ptr) while (ptr)
{ {
ptr->mon_prev_status = ptr->server->status; ptr->mon_prev_status = ptr->server->status;
monitorDatabase(mon, ptr); monitorDatabase(ptr);
/* Log server status change */ /* Log server status change */
if (mon_status_changed(ptr)) if (mon_status_changed(ptr))
@ -618,7 +593,7 @@ monitorMain(void *arg)
* UUID and cluster_size each node reports: * UUID and cluster_size each node reports:
* no multiple clusters UUID are allowed. * no multiple clusters UUID are allowed.
*/ */
set_galera_cluster(mon); set_galera_cluster();
/* /*
* Let's select a master server: * Let's select a master server:
@ -628,18 +603,18 @@ monitorMain(void *arg)
*/ */
/* get the candidate master, following MXS_MIN(node_id) rule */ /* get the candidate master, following MXS_MIN(node_id) rule */
candidate_master = get_candidate_master(mon); candidate_master = get_candidate_master();
handle->master = set_cluster_master(handle->master, candidate_master, master_stickiness); m_master = set_cluster_master(m_master, candidate_master, master_stickiness);
ptr = mon->monitored_servers; ptr = m_monitor->monitored_servers;
while (ptr) while (ptr)
{ {
const int repl_bits = (SERVER_SLAVE | SERVER_MASTER | SERVER_MASTER_STICKINESS); const int repl_bits = (SERVER_SLAVE | SERVER_MASTER | SERVER_MASTER_STICKINESS);
if (SERVER_IS_JOINED(ptr->server) && !handle->disableMasterRoleSetting) if (SERVER_IS_JOINED(ptr->server) && !m_disableMasterRoleSetting)
{ {
if (ptr != handle->master) if (ptr != m_master)
{ {
/* set the Slave role and clear master stickiness */ /* set the Slave role and clear master stickiness */
server_clear_set_status(ptr->server, repl_bits, SERVER_SLAVE); server_clear_set_status(ptr->server, repl_bits, SERVER_SLAVE);
@ -647,7 +622,7 @@ monitorMain(void *arg)
else else
{ {
if (candidate_master && if (candidate_master &&
handle->master->server->node_id != candidate_master->server->node_id) m_master->server->node_id != candidate_master->server->node_id)
{ {
/* set master role and master stickiness */ /* set master role and master stickiness */
server_clear_set_status(ptr->server, repl_bits, server_clear_set_status(ptr->server, repl_bits,
@ -687,22 +662,22 @@ monitorMain(void *arg)
* After updating the status of all servers, check if monitor events * After updating the status of all servers, check if monitor events
* need to be launched. * need to be launched.
*/ */
mon_process_state_changes(mon, handle->script, handle->events); mon_process_state_changes(m_monitor, m_script, m_events);
mon_hangup_failed_servers(mon); mon_hangup_failed_servers(m_monitor);
servers_status_current_to_pending(mon); servers_status_current_to_pending(m_monitor);
/* Set the global var "wsrep_sst_donor" /* Set the global var "wsrep_sst_donor"
* with a sorted list of "wsrep_node_name" for slave nodes * with a sorted list of "wsrep_node_name" for slave nodes
*/ */
if (handle->set_donor_nodes) if (m_set_donor_nodes)
{ {
update_sst_donor_nodes(mon, is_cluster); update_sst_donor_nodes(is_cluster);
} }
store_server_journal(mon, NULL); store_server_journal(m_monitor, NULL);
release_monitor_servers(mon); release_monitor_servers(m_monitor);
} }
} }
@ -715,11 +690,10 @@ monitorMain(void *arg)
* @param servers The monitored servers list * @param servers The monitored servers list
* @return The candidate master on success, NULL on failure * @return The candidate master on success, NULL on failure
*/ */
static MXS_MONITORED_SERVER *get_candidate_master(MXS_MONITOR* mon) MXS_MONITORED_SERVER *GaleraMonitor::get_candidate_master()
{ {
MXS_MONITORED_SERVER *moitor_servers = mon->monitored_servers; MXS_MONITORED_SERVER *moitor_servers = m_monitor->monitored_servers;
MXS_MONITORED_SERVER *candidate_master = NULL; MXS_MONITORED_SERVER *candidate_master = NULL;
GALERA_MONITOR* handle = static_cast<GALERA_MONITOR*>(mon->instance);
long min_id = -1; long min_id = -1;
int minval = INT_MAX; int minval = INT_MAX;
int currval; int currval;
@ -731,7 +705,7 @@ static MXS_MONITORED_SERVER *get_candidate_master(MXS_MONITOR* mon)
moitor_servers->server->depth = 0; moitor_servers->server->depth = 0;
char buf[50]; // Enough to hold most numbers char buf[50]; // Enough to hold most numbers
if (handle->use_priority && server_get_parameter_nolock(moitor_servers->server, "priority", buf, sizeof(buf))) if (m_use_priority && server_get_parameter_nolock(moitor_servers->server, "priority", buf, sizeof(buf)))
{ {
/** The server has a priority */ /** The server has a priority */
if ((currval = atoi(buf)) > 0) if ((currval = atoi(buf)) > 0)
@ -758,8 +732,8 @@ static MXS_MONITORED_SERVER *get_candidate_master(MXS_MONITOR* mon)
moitor_servers = moitor_servers->next; moitor_servers = moitor_servers->next;
} }
if (!handle->use_priority && !handle->disableMasterFailback && if (!m_use_priority && !m_disableMasterFailback &&
handle->root_node_as_master && min_id > 0) m_root_node_as_master && min_id > 0)
{ {
/** The monitor couldn't find the node with wsrep_local_index of 0. /** The monitor couldn't find the node with wsrep_local_index of 0.
* This means that we can't connect to the root node of the cluster. * This means that we can't connect to the root node of the cluster.
@ -836,12 +810,11 @@ static MXS_MONITORED_SERVER *set_cluster_master(MXS_MONITORED_SERVER *current_ma
* @param mon The monitor handler * @param mon The monitor handler
* @param is_cluster The number of joined nodes * @param is_cluster The number of joined nodes
*/ */
static void update_sst_donor_nodes(MXS_MONITOR *mon, int is_cluster) void GaleraMonitor::update_sst_donor_nodes(int is_cluster)
{ {
MXS_MONITORED_SERVER *ptr; MXS_MONITORED_SERVER *ptr;
MYSQL_ROW row; MYSQL_ROW row;
MYSQL_RES *result; MYSQL_RES *result;
GALERA_MONITOR *handle = static_cast<GALERA_MONITOR*>(mon->instance);
bool ignore_priority = true; bool ignore_priority = true;
if (is_cluster == 1) if (is_cluster == 1)
@ -866,7 +839,7 @@ static void update_sst_donor_nodes(MXS_MONITOR *mon, int is_cluster)
strcpy(donor_list, DONOR_LIST_SET_VAR); strcpy(donor_list, DONOR_LIST_SET_VAR);
ptr = mon->monitored_servers; ptr = m_monitor->monitored_servers;
/* Create an array of slave nodes */ /* Create an array of slave nodes */
while (ptr) while (ptr)
@ -881,7 +854,7 @@ static void update_sst_donor_nodes(MXS_MONITOR *mon, int is_cluster)
* the server list will be order by default method. * the server list will be order by default method.
*/ */
if (handle->use_priority && if (m_use_priority &&
server_get_parameter_nolock(ptr->server, "priority", NULL, 0)) server_get_parameter_nolock(ptr->server, "priority", NULL, 0))
{ {
ignore_priority = false; ignore_priority = false;
@ -890,14 +863,14 @@ static void update_sst_donor_nodes(MXS_MONITOR *mon, int is_cluster)
ptr = ptr->next; ptr = ptr->next;
} }
if (ignore_priority && handle->use_priority) if (ignore_priority && m_use_priority)
{ {
MXS_DEBUG("Use priority is set but no server has priority parameter. " MXS_DEBUG("Use priority is set but no server has priority parameter. "
"Donor server list will be ordered by 'wsrep_local_index'"); "Donor server list will be ordered by 'wsrep_local_index'");
} }
/* Set order type */ /* Set order type */
bool sort_order = (!ignore_priority) && (int)handle->use_priority; bool sort_order = (!ignore_priority) && (int)m_use_priority;
/* Sort the array */ /* Sort the array */
qsort(node_list, qsort(node_list,
@ -1072,11 +1045,11 @@ static int compare_node_priority (const void *a, const void *b)
* *
* @param handle The Galera specific data * @param handle The Galera specific data
*/ */
static void reset_cluster_info(GALERA_MONITOR *handle) void GaleraMonitor::reset_cluster_info()
{ {
int n_nodes = 0; int n_nodes = 0;
HASHITERATOR *iterator; HASHITERATOR *iterator;
HASHTABLE *table = handle->galera_nodes_info; HASHTABLE *table = m_galera_nodes_info;
void *key; void *key;
/* Delete all entries in the hashtable */ /* Delete all entries in the hashtable */
@ -1153,13 +1126,12 @@ static void nodeval_free(GALERA_NODE_INFO *in)
* *
* @param mon The Monitor Instance * @param mon The Monitor Instance
*/ */
static void set_galera_cluster(MXS_MONITOR *mon) void GaleraMonitor::set_galera_cluster()
{ {
GALERA_MONITOR *handle = static_cast<GALERA_MONITOR*>(mon->instance);
int ret = false; int ret = false;
int n_nodes = 0; int n_nodes = 0;
HASHITERATOR *iterator; HASHITERATOR *iterator;
HASHTABLE *table = handle->galera_nodes_info; HASHTABLE *table = m_galera_nodes_info;
char *key; char *key;
GALERA_NODE_INFO *value; GALERA_NODE_INFO *value;
int cluster_size = 0; int cluster_size = 0;
@ -1209,8 +1181,7 @@ static void set_galera_cluster(MXS_MONITOR *mon)
* Special cases for n_nodes = 0 or 1. * Special cases for n_nodes = 0 or 1.
* If cluster_size > 1 there is rule * If cluster_size > 1 there is rule
*/ */
ret = detect_cluster_size(handle, ret = detect_cluster_size(n_nodes,
n_nodes,
cluster_uuid, cluster_uuid,
cluster_size); cluster_size);
/** /**
@ -1220,15 +1191,15 @@ static void set_galera_cluster(MXS_MONITOR *mon)
if (ret || (!ret && n_nodes != 1)) if (ret || (!ret && n_nodes != 1))
{ {
/* Set the new cluster_uuid */ /* Set the new cluster_uuid */
MXS_FREE(handle->cluster_info.c_uuid); MXS_FREE(m_cluster_info.c_uuid);
handle->cluster_info.c_uuid = ret ? MXS_STRDUP(cluster_uuid) : NULL; m_cluster_info.c_uuid = ret ? MXS_STRDUP(cluster_uuid) : NULL;
handle->cluster_info.c_size = cluster_size; m_cluster_info.c_size = cluster_size;
} }
/** /**
* Set the JOINED status in cluster members only, if any. * Set the JOINED status in cluster members only, if any.
*/ */
set_cluster_members(mon); set_cluster_members();
} }
/** /**
@ -1240,22 +1211,21 @@ static void set_galera_cluster(MXS_MONITOR *mon)
* *
* @param mon The Monitor Instance * @param mon The Monitor Instance
*/ */
static void set_cluster_members(MXS_MONITOR *mon) void GaleraMonitor::set_cluster_members()
{ {
GALERA_MONITOR *handle = static_cast<GALERA_MONITOR*>(mon->instance);
GALERA_NODE_INFO *value; GALERA_NODE_INFO *value;
MXS_MONITORED_SERVER *ptr; MXS_MONITORED_SERVER *ptr;
char *c_uuid = handle->cluster_info.c_uuid; char *c_uuid = m_cluster_info.c_uuid;
int c_size = handle->cluster_info.c_size; int c_size = m_cluster_info.c_size;
ptr = mon->monitored_servers; ptr = m_monitor->monitored_servers;
while (ptr) while (ptr)
{ {
/* Fetch cluster info for this server, if any */ /* Fetch cluster info for this server, if any */
value = static_cast<GALERA_NODE_INFO*>(hashtable_fetch(handle->galera_nodes_info, value = static_cast<GALERA_NODE_INFO*>(hashtable_fetch(m_galera_nodes_info,
ptr->server->name)); ptr->server->name));
if (value && handle->cluster_info.c_uuid) if (value && m_cluster_info.c_uuid)
{ {
/* Check whether this server is a candidate member */ /* Check whether this server is a candidate member */
if (!SERVER_IN_MAINT(ptr->server) && if (!SERVER_IN_MAINT(ptr->server) &&
@ -1306,14 +1276,13 @@ static void set_cluster_members(MXS_MONITOR *mon)
* @param cluster_size Possible cluster_size in nodes * @param cluster_size Possible cluster_size in nodes
* @return True is a cluster can be set * @return True is a cluster can be set
*/ */
static bool detect_cluster_size(const GALERA_MONITOR *handle, bool GaleraMonitor::detect_cluster_size(const int n_nodes,
const int n_nodes, const char *candidate_uuid,
const char *candidate_uuid, const int candidate_size)
const int candidate_size)
{ {
bool ret = false; bool ret = false;
char *c_uuid = handle->cluster_info.c_uuid; char *c_uuid = m_cluster_info.c_uuid;
int c_size = handle->cluster_info.c_size; int c_size = m_cluster_info.c_size;
/** /**
* Decide whether we have a cluster * Decide whether we have a cluster

View File

@ -25,11 +25,11 @@
* @endverbatim * @endverbatim
*/ */
#include <maxscale/cdefs.h> #include <maxscale/cppdefs.hh>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <maxscale/monitor.h> #include <maxscale/monitor.hh>
#include <maxscale/spinlock.h> #include <maxscale/spinlock.h>
#include <maxscale/thread.h> #include <maxscale/thread.h>
#include <mysql.h> #include <mysql.h>
@ -74,27 +74,55 @@ typedef struct galera_cluster_info
/** /**
* The handle for an instance of a Galera Monitor module * The handle for an instance of a Galera Monitor module
*/ */
struct GALERA_MONITOR : public MXS_MONITOR_INSTANCE class GaleraMonitor : public MXS_MONITOR_INSTANCE
{ {
THREAD thread; /**< Monitor thread */ public:
int shutdown; /**< Flag to shutdown the monitor thread */ GaleraMonitor(const GaleraMonitor&) = delete;
int status; /**< Monitor status */ GaleraMonitor& operator = (const GaleraMonitor&) = delete;
unsigned long id; /**< Monitor ID */
int disableMasterFailback; /**< Monitor flag for Galera Cluster Master failback */ static GaleraMonitor* create(MXS_MONITOR* monitor);
int availableWhenDonor; /**< Monitor flag for Galera Cluster Donor availability */ void destroy();
bool disableMasterRoleSetting; /**< Monitor flag to disable setting master role */ bool start(const MXS_CONFIG_PARAMETER* param);
MXS_MONITORED_SERVER *master; /**< Master server for MySQL Master/Slave replication */ void stop();
char* script; /**< Launchable script */ void diagnostics(DCB* dcb) const;
bool root_node_as_master; /**< Whether we require that the Master should json_t* diagnostics_json() const;
private:
THREAD m_thread; /**< Monitor thread */
int m_shutdown; /**< Flag to shutdown the monitor thread */
int m_status; /**< Monitor status */
unsigned long m_id; /**< Monitor ID */
int m_disableMasterFailback; /**< Monitor flag for Galera Cluster Master failback */
int m_availableWhenDonor; /**< Monitor flag for Galera Cluster Donor availability */
bool m_disableMasterRoleSetting; /**< Monitor flag to disable setting master role */
MXS_MONITORED_SERVER *m_master; /**< Master server for MySQL Master/Slave replication */
char* m_script; /**< Launchable script */
bool m_root_node_as_master; /**< Whether we require that the Master should
* have a wsrep_local_index of 0 */ * have a wsrep_local_index of 0 */
bool use_priority; /**< Use server priorities */ bool m_use_priority; /**< Use server priorities */
uint64_t events; /**< Enabled monitor events */ uint64_t m_events; /**< Enabled monitor events */
bool set_donor_nodes; /**< set the wrep_sst_donor variable with an bool m_set_donor_nodes; /**< set the wrep_sst_donor variable with an
* ordered list of nodes */ * ordered list of nodes */
HASHTABLE *galera_nodes_info; /**< Contains Galera Cluster variables of all nodes */ HASHTABLE *m_galera_nodes_info; /**< Contains Galera Cluster variables of all nodes */
GALERA_CLUSTER_INFO cluster_info; /**< Contains Galera cluster info */ GALERA_CLUSTER_INFO m_cluster_info; /**< Contains Galera cluster info */
MXS_MONITOR* monitor; /**< Pointer to generic monitor structure */ MXS_MONITOR* m_monitor; /**< Pointer to generic monitor structure */
bool checked; /**< Whether server access has been checked */ bool m_checked; /**< Whether server access has been checked */
GaleraMonitor(MXS_MONITOR* monitor);
~GaleraMonitor();
bool detect_cluster_size(const int n_nodes,
const char *candidate_uuid,
const int candidate_size);
MXS_MONITORED_SERVER *get_candidate_master();
void monitorDatabase(MXS_MONITORED_SERVER *database);
void reset_cluster_info();
void set_cluster_members();
void set_galera_cluster();
void update_sst_donor_nodes(int is_cluster);
void main();
static void main(void* data);
}; };
#endif #endif