Master can be a slave

This is possible if read_only is turned ON on the master and there is
no alternative master to swap to.
This commit is contained in:
Esa Korhonen
2018-08-20 15:24:21 +03:00
parent 1c508cd413
commit 44a57dbefd
2 changed files with 25 additions and 24 deletions

View File

@ -24,8 +24,6 @@
using std::string; using std::string;
using maxscale::string_printf; using maxscale::string_printf;
static const int64_t MASTER_BITS = SERVER_MASTER | SERVER_WAS_MASTER;
/** /**
* Generic depth-first search. Iterates through child nodes (slaves) and runs the 'visit_func' on the nodes. * Generic depth-first search. Iterates through child nodes (slaves) and runs the 'visit_func' on the nodes.
* Isn't flexible enough for all uses. * Isn't flexible enough for all uses.
@ -420,32 +418,35 @@ void MariaDBMonitor::assign_server_roles()
server->clear_status(remove_bits); server->clear_status(remove_bits);
} }
// Check the the master node, label it as the [Master] if... // Check the the master node, label it as the [Master] if
if (m_master) // 1) the node has slaves, even if their slave sql threads are stopped
// 2) or detect standalone master is on.
if (m_master && (!m_master->m_node.children.empty() || m_detect_standalone_master))
{ {
// the node has slaves, even if their slave sql threads are stopped ... if (m_master->is_running())
if (!m_master->m_node.children.empty() ||
// or detect standalone master is on ...
m_detect_standalone_master)
{ {
if (m_master->is_running()) if (m_master->is_read_only())
{ {
// Master is running, assign bits for valid replication. // Special case: read_only is ON on a running master but there is no alternative master.
m_master->clear_status(SERVER_SLAVE | SERVER_RELAY); // In this case, label the master as a slave and proceed normally.
m_master->set_status(MASTER_BITS); m_master->set_status(SERVER_SLAVE);
// Run another graph search, this time assigning slaves.
reset_node_index_info();
assign_slave_and_relay_master(m_master);
} }
else if (m_detect_stale_master && (m_master->had_status(SERVER_WAS_MASTER))) else
{ {
// The master is not running but it was the master last round and may have running slaves // Master is running and writable.
// who have up-to-date events. Label any slaves, whether running or not with SERVER_WAS_SLAVE. m_master->set_status(SERVER_MASTER | SERVER_WAS_MASTER);
m_master->set_status(SERVER_WAS_MASTER);
reset_node_index_info();
assign_slave_and_relay_master(m_master);
} }
} }
else if (m_detect_stale_master && (m_master->had_status(SERVER_WAS_MASTER)))
{
// The master is not running but it was the master last round and
// may have running slaves who have up-to-date events.
m_master->set_status(SERVER_WAS_MASTER);
}
// Run another graph search, this time assigning slaves.
reset_node_index_info();
assign_slave_and_relay_master(m_master);
} }
if (!m_ignore_external_masters) if (!m_ignore_external_masters)
@ -553,7 +554,6 @@ void MariaDBMonitor::assign_slave_and_relay_master(MariaDBServer* start_node)
// The slave only gets the slave flags if it's running. // The slave only gets the slave flags if it's running.
// TODO: If slaves with broken links should be given different flags, add that here. // TODO: If slaves with broken links should be given different flags, add that here.
slave->clear_status(MASTER_BITS);
if (slave->is_running()) if (slave->is_running())
{ {
slave->set_status(SERVER_SLAVE); slave->set_status(SERVER_SLAVE);
@ -563,7 +563,8 @@ void MariaDBMonitor::assign_slave_and_relay_master(MariaDBServer* start_node)
} }
// Finally, if the node itself is a running slave and has slaves of its own, label it as relay. // Finally, if the node itself is a running slave and has slaves of its own, label it as relay.
if (parent_has_live_link && parent->has_status(SERVER_SLAVE | SERVER_RUNNING) && has_slaves) if (parent != m_master && parent_has_live_link &&
parent->has_status(SERVER_SLAVE | SERVER_RUNNING) && has_slaves)
{ {
parent->set_status(SERVER_RELAY); parent->set_status(SERVER_RELAY);
} }

View File

@ -1367,7 +1367,7 @@ bool MariaDBMonitor::cluster_supports_failover(string* reasons_out)
rval = false; rval = false;
} }
if (server->is_slave()) if (server->is_slave() && !server->m_slave_status.empty())
{ {
if (server->m_slave_status.size() > 1) if (server->m_slave_status.size() > 1)
{ {