Pick node with index of 0 as the Galera master

When a Galera cluster loses a member, it will recalculate the
wsrep_local_index values. As the index is zero-based, we can be certain
that in a valid cluster there will always be a node with an index of 0.

If the galeramon can't find a node with an index of 0, it means that
either the cluster hasn't stabilized and there's a pending recalculation
of the index or that there's no connectivity between MaxScale and the node
with the index value 0.

With this change and default settings, active-active MaxScale setups with
Galera clusters should always choose the same node as the master.
This commit is contained in:
Markus Mäkelä
2016-12-16 19:33:05 +02:00
parent 067d48ddc6
commit 2b5ec8f162
4 changed files with 55 additions and 16 deletions

View File

@ -145,6 +145,7 @@ startMonitor(MONITOR *mon, const CONFIG_PARAMETER *params)
handle->disableMasterRoleSetting = 0;
handle->master = NULL;
handle->script = NULL;
handle->root_node_as_master = true;
handle->use_priority = false;
memset(handle->events, false, sizeof(handle->events));
spinlock_init(&handle->lock);
@ -165,6 +166,10 @@ startMonitor(MONITOR *mon, const CONFIG_PARAMETER *params)
{
handle->disableMasterRoleSetting = config_truth_value(params->value);
}
else if (!strcmp(params->name, "root_node_as_master"))
{
handle->root_node_as_master = config_truth_value(params->value);
}
else if (!strcmp(params->name, "use_priority"))
{
handle->use_priority = config_truth_value(params->value);
@ -548,29 +553,27 @@ monitorMain(void *arg)
const int repl_bits = (SERVER_SLAVE | SERVER_MASTER | SERVER_MASTER_STICKINESS);
if (SERVER_IS_JOINED(ptr->server))
{
if (handle->master)
if (ptr != handle->master)
{
if (ptr != handle->master)
/* set the Slave role and clear master stickiness */
server_clear_set_status(ptr->server, repl_bits, SERVER_SLAVE);
}
else
{
if (candidate_master &&
handle->master->server->node_id != candidate_master->server->node_id)
{
/* set the Slave role and clear master stickiness */
server_clear_set_status(ptr->server, repl_bits, SERVER_SLAVE);
/* set master role and master stickiness */
server_clear_set_status(ptr->server, repl_bits,
(SERVER_MASTER | SERVER_MASTER_STICKINESS));
}
else
{
if (candidate_master &&
handle->master->server->node_id != candidate_master->server->node_id)
{
/* set master role and master stickiness */
server_clear_set_status(ptr->server, repl_bits,
(SERVER_MASTER | SERVER_MASTER_STICKINESS));
}
else
{
/* set master role and clear master stickiness */
server_clear_set_status(ptr->server, repl_bits, SERVER_MASTER);
}
/* set master role and clear master stickiness */
server_clear_set_status(ptr->server, repl_bits, SERVER_MASTER);
}
}
is_cluster++;
}
else
@ -674,6 +677,17 @@ static MONITOR_SERVERS *get_candidate_master(MONITOR* mon)
moitor_servers = moitor_servers->next;
}
if (!handle->use_priority && !handle->disableMasterFailback &&
handle->root_node_as_master && min_id > 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.
*
* If the node is down, the cluster would recalculate the index values
* and we would find it. In this case, we just can't connect to it. */
candidate_master = NULL;
}
return candidate_master;
}

View File

@ -58,6 +58,8 @@ typedef struct
int disableMasterRoleSetting; /**< Monitor flag to disable setting master role */
MONITOR_SERVERS *master; /**< Master server for MySQL Master/Slave replication */
char* script;
bool root_node_as_master; /**< Whether we require that the Master should
* have a wsrep_local_index of 0 */
bool use_priority; /*< Use server priorities */
bool events[MAX_MONITOR_EVENT]; /*< enabled events */
} GALERA_MONITOR;