diff --git a/server/modules/monitor/mariadbmon/cluster_discovery.cc b/server/modules/monitor/mariadbmon/cluster_discovery.cc index 5332fbe48..75a888551 100644 --- a/server/modules/monitor/mariadbmon/cluster_discovery.cc +++ b/server/modules/monitor/mariadbmon/cluster_discovery.cc @@ -27,8 +27,6 @@ static bool check_replicate_wild_do_table(MXS_MONITORED_SERVER* database); static bool check_replicate_wild_ignore_table(MXS_MONITORED_SERVER* database); static const char HB_TABLE_NAME[] = "maxscale_schema.replication_heartbeat"; -static const char SERVER_DISQUALIFIED[] = "Server '%s' was disqualified from new master selection because " - "it is %s."; static const int64_t MASTER_BITS = SERVER_MASTER | SERVER_WAS_MASTER; static const int64_t SLAVE_BITS = SERVER_SLAVE | SERVER_WAS_SLAVE; @@ -383,6 +381,9 @@ void MariaDBMonitor::build_replication_graph() * an old "Master_Server_Id"- value is read from a slave which is still trying to connect to * a new master. However, a server is only designated [Slave] if both IO- and SQL-threads are * running fine, so the faulty graph does not cause wrong status settings. */ + + /* IF THIS PART IS CHANGED, CHANGE THE COMPARISON IN 'sstatus_arrays_topology_equal' + * (in MariaDBServer) accordingly so that any possible topology changes are detected. */ auto master_id = slave_conn.master_server_id; if (slave_conn.slave_io_running != SlaveStatus::SLAVE_IO_NO && master_id > 0) { @@ -977,15 +978,20 @@ static string disqualify_reasons_to_string(MariaDBServer* disqualified) * the current master making it unsuitable. Because of this, the method can be quite vocal and not * consider the previous master. * + * @param msg_out Message output. Includes explanations on why potential candidates were not selected. * @return The master with most slaves */ -MariaDBServer* MariaDBMonitor::find_topology_master_server() +MariaDBServer* MariaDBMonitor::find_topology_master_server(string* msg_out) { /* Finding the best master server may get somewhat tricky if the graph is complicated. The general * criteria for the best master is that it reaches the most slaves (possibly in multiple layers and * cycles). To avoid having to calculate this reachability (doable by a recursive search) to all nodes, * let's use the knowledge that the best master is either a server with no masters (external ones don't - * count) or is part of a cycle. The server must be running and writable to be eligible. */ + * count) or is part of a cycle with no out-cycle masters. The server must be running and writable + * to be eligible. */ + string messages; + string separator; + const char disq[] = "is not a valid master candidate because it is "; ServerArray master_candidates; for (auto iter = m_servers.begin(); iter != m_servers.end(); iter++) { @@ -999,7 +1005,8 @@ MariaDBServer* MariaDBMonitor::find_topology_master_server() else { string reasons = disqualify_reasons_to_string(server); - MXS_WARNING(SERVER_DISQUALIFIED, server->name(), reasons.c_str()); + messages += separator + "'" + server->name() + "' " + disq + reasons + "."; + separator = "\n"; } } } @@ -1021,31 +1028,25 @@ MariaDBServer* MariaDBMonitor::find_topology_master_server() else { // No single server in the cycle was viable. - const char WARN_MSG[] = "No valid master server could be found in the cycle with " - "servers '%s'."; + const char no_valid_servers[] = "No valid master server could be found in the cycle with " + "servers"; string server_names = monitored_servers_to_string(cycle_members); - MXS_WARNING(WARN_MSG, server_names.c_str()); + messages += separator + no_valid_servers + " '" + server_names + "'."; + separator = "\n"; for (auto iter2 = cycle_members.begin(); iter2 != cycle_members.end(); iter2++) { MariaDBServer* disqualified_server = *iter2; string reasons = disqualify_reasons_to_string(disqualified_server); - MXS_WARNING(SERVER_DISQUALIFIED, disqualified_server->name(), reasons.c_str()); + messages += separator + "'" + disqualified_server->name() + "' " + disq + reasons + "."; + separator = "\n"; } } } } - MariaDBServer* found_master = NULL; - if (!master_candidates.empty()) - { - found_master = find_best_reach_server(master_candidates); - } - else - { - MXS_WARNING("No valid master servers in the cluster."); - } - return found_master; + *msg_out = messages; + return master_candidates.empty() ? NULL : find_best_reach_server(master_candidates); } static void node_reach_visit(MariaDBServer* node, int* reach) @@ -1176,7 +1177,7 @@ void MariaDBMonitor::assign_slave_and_relay_master(MariaDBServer* node) { MariaDBServer* slave = *iter; // If the node has an index, it has already been labeled master/slave and visited. Even when this - // is the case, the slave has to be checked to get correct [Relay Master] labels. + // is the case, the node has to be checked to get correct [Relay Master] labels. if (slave->m_node.index == NodeData::INDEX_NOT_VISITED) { slave->clear_status(MASTER_BITS); @@ -1214,10 +1215,15 @@ void MariaDBMonitor::assign_slave_and_relay_master(MariaDBServer* node) } // Finally, if the node itself is a slave and has slaves of its own, label it as relay slave. - if ((node->m_server_base->pending_status & SERVER_SLAVE) && slaves > 0) + if (node->has_status(SERVER_SLAVE) && slaves > 0) { node->set_status(SERVER_RELAY_MASTER); } + // If the node is a binlog relay, remove any slave bits that may have been set. Relay master bit can stay. + if (node->m_version == MariaDBServer::version::BINLOG_ROUTER) + { + node->clear_status(SERVER_SLAVE); + } } /** @@ -1248,7 +1254,7 @@ bool MariaDBMonitor::master_no_longer_valid(std::string* reason_out) if (!m_master->m_node.parents.empty()) { rval = true; - *reason_out = "it has started replicating from another server in the cluster."; + *reason_out = "it has started replicating from another server in the cluster"; } } // 4) The master was part of a cycle but is no longer, or one of the servers in the cycle is @@ -1265,7 +1271,7 @@ bool MariaDBMonitor::master_no_longer_valid(std::string* reason_out) rval = true; ServerArray& old_members = m_master_cycle_status.cycle_members; string server_names_old = monitored_servers_to_string(old_members); - *reason_out = "it is no longer in the multimaster group (" + server_names_old + ")."; + *reason_out = "it is no longer in the multimaster group (" + server_names_old + ")"; } // 4b) The master is still in a cycle but the cycle has gained a master outside of the cycle. else @@ -1276,7 +1282,7 @@ bool MariaDBMonitor::master_no_longer_valid(std::string* reason_out) rval = true; string server_names_current = monitored_servers_to_string(current_members); *reason_out = "a server in the master's multimaster group (" + server_names_current + - ") is replicating from a server not in the group."; + ") is replicating from a server not in the group"; } } } diff --git a/server/modules/monitor/mariadbmon/mariadbmon.cc b/server/modules/monitor/mariadbmon/mariadbmon.cc index 890503a28..25efbbc63 100644 --- a/server/modules/monitor/mariadbmon/mariadbmon.cc +++ b/server/modules/monitor/mariadbmon/mariadbmon.cc @@ -293,6 +293,7 @@ json_t* MariaDBMonitor::diagnostics_json() const */ void MariaDBMonitor::update_server(MariaDBServer& server) { + server.m_topology_changed = false; MXS_MONITORED_SERVER* mon_srv = server.m_server_base; /* Monitor server if not in maintenance. */ bool in_maintenance = server.is_in_maintenance(); @@ -358,11 +359,22 @@ void MariaDBMonitor::update_server(MariaDBServer& server) void MariaDBMonitor::pre_loop() { - // MonitorInstance loaded from the journal the current master into its - // m_master member variable, we want the corresponding MariaDBServer into - // our own m_master varaible. + // MonitorInstance read the journal and has the last known master in its m_master member variable. + // Write the corresponding MariaDBServer into the class-specific m_master variable. m_master = MonitorInstance::m_master ? get_server_info(MonitorInstance::m_master) : NULL; + /* It's possible (e.g. after switchover) that the MXS_MONITORED_SERVER-objects have live connections + * from last time the monitor was active. These should be closed to avoid confusing the monitor and + * making it clear this is a new start. This can be removed once monitor pause/resume is implemented. */ + for (MariaDBServer* server : m_servers) + { + if (server->m_server_base->con) + { + mysql_close(server->m_server_base->con); + server->m_server_base->con = NULL; + } + } + if (m_detect_replication_lag) { check_maxscale_schema_replication(); @@ -382,68 +394,115 @@ void MariaDBMonitor::tick() mon_srv->mon_prev_status = status; } - // Query all servers for their status. Update the server id array. - m_servers_by_id.clear(); + // Query all servers for their status. + bool topology_changed = false; for (auto iter = m_servers.begin(); iter != m_servers.end(); iter++) { MariaDBServer* server = *iter; update_server(*server); - - if (server->m_server_id != SERVER_ID_UNKNOWN) + if (server->m_topology_changed) { - IdToServerMap::value_type new_val(server->m_server_id, server); - m_servers_by_id.insert(new_val); + topology_changed = true; } } - build_replication_graph(); - find_graph_cycles(); - string reason; - MariaDBServer* root_master = m_master; // TODO: Refactor this out by reducing use of root_master - if (master_no_longer_valid(&reason)) + if (topology_changed) { - if (m_master && !reason.empty()) + // This means that a server id or a slave connection has changed, or read_only was set. + // Update the server id array and check various things. + m_servers_by_id.clear(); + for (auto server : m_servers) { - MXS_WARNING("The previous master server '%s' is no longer a valid master because %s", - m_master->name(), reason.c_str()); + m_servers_by_id[server->m_server_id] = server; } + build_replication_graph(); + find_graph_cycles(); + // Find the server that looks like it would be the best master. It does not yet overwrite the + // current master. + string topology_messages; + MariaDBServer* root_master = find_topology_master_server(&topology_messages); - // The current master is no longer ok (or it never was). Find another. Master changes are logged - // by the log_master_changes()-method. - root_master = find_topology_master_server(); - if (root_master) + // Check if current master is still valid. + string reason; + if (master_no_longer_valid(&reason)) { - m_master = root_master; - // A new master has been set. Save some data regarding the type of the master. - int new_cycle_id = m_master->m_node.cycle; - m_master_cycle_status.cycle_id = new_cycle_id; - if (new_cycle_id == NodeData::CYCLE_NONE) + if (m_master && !reason.empty()) { - m_master_cycle_status.cycle_members.clear(); + MXS_WARNING("The previous master server '%s' is no longer a valid master because %s. " + "Selecting new master.", m_master->name(), reason.c_str()); } else { - m_master_cycle_status.cycle_members = m_cycles[new_cycle_id]; + MXS_NOTICE("Selecting master server."); } + + // The current master is no longer ok (or it never was). Change the master, even though this may + // break replication. Master changes are logged by the log_master_changes()-method. + if (!topology_messages.empty()) + { + MXS_WARNING("%s", topology_messages.c_str()); + } + + m_master = root_master; + if (m_master) + { + // A new master has been set. Save some data regarding the type of the master. + int new_cycle_id = m_master->m_node.cycle; + m_master_cycle_status.cycle_id = new_cycle_id; + if (new_cycle_id == NodeData::CYCLE_NONE) + { + m_master_cycle_status.cycle_members.clear(); + } + else + { + m_master_cycle_status.cycle_members = m_cycles[new_cycle_id]; + } + MXS_NOTICE("'%s' is the best master candidate.", m_master->name()); + } + else + { + // The current master cannot be used and no proper candidate exists. + m_master_cycle_status.cycle_id = NodeData::CYCLE_NONE; + m_master_cycle_status.cycle_members.clear(); + MXS_WARNING("No valid master servers found."); + } + } + else if (root_master && m_master != root_master) + { + // Master is still valid but it is no longer the best master. Print a warning. + MXS_WARNING("'%s' is a better master candidate than the current master '%s'. " + "Master will change if '%s' is no longer a valid master.", + root_master->name(), m_master->name(), m_master->name()); } } + // Always re-assign master, slave etc bits as these depend on other factors outside topology + // (e.g. slave sql state). assign_master_and_slave(); if (!m_ignore_external_masters) { - // Do a sweep through all the nodes in the cluster (even the master) and mark other states. - for (auto iter = m_servers.begin(); iter != m_servers.end(); iter++) + // Do a sweep through all the nodes in the cluster (even the master) and mark external slaves. + for (MariaDBServer* server : m_servers) { - MariaDBServer* server = *iter; if (!server->m_node.external_masters.empty()) { server->set_status(SERVER_SLAVE_OF_EXT_MASTER); } - else - { - server->clear_status(SERVER_SLAVE_OF_EXT_MASTER); - } + } + } + + /* Check if need to use standalone master. TODO: Rewrite these methods. */ + if (m_detect_standalone_master) + { + if (standalone_master_required()) + { + // Other servers have died, set last remaining server as master + set_standalone_master(); + } + else + { + m_warn_set_standalone_master = true; } } @@ -454,67 +513,13 @@ void MariaDBMonitor::tick() update_external_master(); } - // Clear SERVER_SLAVE from binlog relays - for (auto iter = m_servers.begin(); iter != m_servers.end(); iter++) - { - /* Remove SLAVE status if this server is a Binlog Server relay */ - if ((*iter)->m_version == MariaDBServer::version::BINLOG_ROUTER) - { - monitor_clear_pending_status((*iter)->m_server_base, SERVER_SLAVE); - } - } - - /* Update server status from monitor pending status on that server*/ - for (auto iter = m_servers.begin(); iter != m_servers.end(); iter++) - { - update_server_states(**iter, root_master); - } - - /** Now that all servers have their status correctly set, we can check - if we need to use standalone master. */ - if (m_detect_standalone_master) - { - if (standalone_master_required()) - { - // Other servers have died, set last remaining server as master - if (set_standalone_master()) - { - // Update the root_master to point to the standalone master - root_master = m_master; - } - } - else - { - m_warn_set_standalone_master = true; - } - } - - if (root_master && root_master->is_master()) - { - // Clear slave and stale slave status bits from current master - root_master->clear_status(SERVER_SLAVE | SERVER_WAS_SLAVE); - - /** - * Clear external slave status from master if configured to do so. - * This allows parts of a multi-tiered replication setup to be used - * in MaxScale. - */ - if (m_ignore_external_masters) - { - root_master->clear_status(SERVER_SLAVE_OF_EXT_MASTER); - } - } - - ss_dassert(root_master == NULL || root_master == m_master); - ss_dassert(root_master == NULL || - ((root_master->m_server_base->pending_status & (SERVER_SLAVE | SERVER_MASTER)) != - (SERVER_SLAVE | SERVER_MASTER))); + // Sanity check. Master may not be both slave and master. + ss_dassert(m_master == NULL || !m_master->has_status(SERVER_SLAVE | SERVER_MASTER)); /* Generate the replication heartbeat event by performing an update */ - if (m_detect_replication_lag && root_master && - (root_master->is_master() || root_master->is_relay_server())) + if (m_detect_replication_lag && m_master && m_master->is_master()) { - measure_replication_lag(root_master); + measure_replication_lag(); } // Update shared status. The next functions read the shared status. TODO: change the following @@ -524,8 +529,7 @@ void MariaDBMonitor::tick() mon_srv->server->status = mon_srv->pending_status; } - /* log master detection failure of first master becomes available after failure */ - log_master_changes(root_master); + log_master_changes(); // Before exiting, we need to store the current master into the m_master // member variable of MonitorInstance so that the right server will be @@ -540,7 +544,11 @@ void MariaDBMonitor::process_state_changes() m_cluster_modified = false; if (m_auto_failover) { - m_cluster_modified = handle_auto_failover(); + if ((m_cluster_modified = handle_auto_failover())) + { + // Force a master selection on next monitor loop, otherwise the old master would stay. + m_master = NULL; + } } // Do not auto-join servers on this monitor loop if a failover (or any other cluster modification) @@ -608,35 +616,29 @@ void MariaDBMonitor::update_external_master() } } -void MariaDBMonitor::measure_replication_lag(MariaDBServer* root_master) +void MariaDBMonitor::measure_replication_lag() { - ss_dassert(root_master); - MXS_MONITORED_SERVER* mon_root_master = root_master->m_server_base; - set_master_heartbeat(root_master); - for (auto iter = m_servers.begin(); iter != m_servers.end(); iter++) + ss_dassert(m_master && m_master->is_master()); + set_master_heartbeat(m_master); + for (MariaDBServer* slave : m_servers) { - MariaDBServer* server = *iter; - MXS_MONITORED_SERVER* ptr = server->m_server_base; - if ((!server->is_in_maintenance()) && server->is_running()) + // No lag measurement for Binlog Server + if (slave->is_slave() && + (slave->m_version == MariaDBServer::version::MARIADB_MYSQL_55 || + slave->m_version == MariaDBServer::version::MARIADB_100)) { - if (ptr->server->node_id != mon_root_master->server->node_id && - (server->is_slave() || server->is_relay_server()) && - (server->m_version == MariaDBServer::version::MARIADB_MYSQL_55 || - server->m_version == MariaDBServer::version::MARIADB_100)) // No select lag for Binlog Server - { - set_slave_heartbeat(server); - } + set_slave_heartbeat(slave); } } } -void MariaDBMonitor::log_master_changes(MariaDBServer* root_master_server) +void MariaDBMonitor::log_master_changes() { - MXS_MONITORED_SERVER* root_master = root_master_server ? root_master_server->m_server_base : NULL; + MXS_MONITORED_SERVER* root_master = m_master ? m_master->m_server_base : NULL; if (root_master && mon_status_changed(root_master) && !(root_master->pending_status & SERVER_WAS_MASTER)) { - if ((root_master->pending_status & SERVER_MASTER) && root_master_server->is_running()) + if ((root_master->pending_status & SERVER_MASTER) && m_master->is_running()) { if (!(root_master->mon_prev_status & SERVER_WAS_MASTER) && !(root_master->pending_status & SERVER_MAINT)) diff --git a/server/modules/monitor/mariadbmon/mariadbmon.hh b/server/modules/monitor/mariadbmon/mariadbmon.hh index 389866e3b..87c70d533 100644 --- a/server/modules/monitor/mariadbmon/mariadbmon.hh +++ b/server/modules/monitor/mariadbmon/mariadbmon.hh @@ -187,19 +187,19 @@ private: bool standalone_master_required(); bool set_standalone_master(); void assign_relay_master(MariaDBServer& serv_info); - void log_master_changes(MariaDBServer* root_master); + void log_master_changes(); void update_gtid_domain(); void update_external_master(); void set_master_heartbeat(MariaDBServer*); void set_slave_heartbeat(MariaDBServer*); - void measure_replication_lag(MariaDBServer* root_master); + void measure_replication_lag(); void check_maxscale_schema_replication(); MXS_MONITORED_SERVER* getServerByNodeId(long); MXS_MONITORED_SERVER* getSlaveOfNodeId(long, slave_down_setting_t); void build_replication_graph(); void tarjan_scc_visit_node(MariaDBServer *node, ServerArray* stack, int *index, int *cycle); void assign_cycle_roles(int cycle); - MariaDBServer* find_topology_master_server(); + MariaDBServer* find_topology_master_server(std::string* msg_out); MariaDBServer* find_best_reach_server(const ServerArray& candidates); void calculate_node_reach(MariaDBServer* node); int calc_reach_visit_node(MariaDBServer* node); diff --git a/server/modules/monitor/mariadbmon/mariadbserver.cc b/server/modules/monitor/mariadbmon/mariadbserver.cc index 895895d94..bef24160b 100644 --- a/server/modules/monitor/mariadbmon/mariadbserver.cc +++ b/server/modules/monitor/mariadbmon/mariadbserver.cc @@ -41,7 +41,6 @@ SlaveStatus::SlaveStatus() MariaDBServer::MariaDBServer(MXS_MONITORED_SERVER* monitored_server, int config_index) : m_server_base(monitored_server) , m_config_index(config_index) - , m_print_update_errormsg(true) , m_version(version::UNKNOWN) , m_server_id(SERVER_ID_UNKNOWN) , m_read_only(false) @@ -50,6 +49,7 @@ MariaDBServer::MariaDBServer(MXS_MONITORED_SERVER* monitored_server, int config_ , m_heartbeat_period(0) , m_latest_event(0) , m_gtid_domain_id(GTID_DOMAIN_UNKNOWN) + , m_print_update_errormsg(true) { ss_dassert(monitored_server); } @@ -174,34 +174,31 @@ bool MariaDBServer::do_show_slave_status(string* errmsg_out) } } - m_slave_status.clear(); + SlaveStatusArray slave_status_new; int nrunning = 0; while (result->next_row()) { - SlaveStatus sstatus; - sstatus.master_host = result->get_string(i_master_host); - sstatus.master_port = result->get_uint(i_master_port); + SlaveStatus sstatus_row; + sstatus_row.master_host = result->get_string(i_master_host); + sstatus_row.master_port = result->get_uint(i_master_port); string last_io_error = result->get_string(i_last_io_error); string last_sql_error = result->get_string(i_last_sql_error); - sstatus.last_error = !last_io_error.empty() ? last_io_error : last_sql_error; + sstatus_row.last_error = !last_io_error.empty() ? last_io_error : last_sql_error; - sstatus.slave_io_running = + sstatus_row.slave_io_running = SlaveStatus::slave_io_from_string(result->get_string(i_slave_io_running)); - sstatus.slave_sql_running = (result->get_string(i_slave_sql_running) == "Yes"); + sstatus_row.slave_sql_running = (result->get_string(i_slave_sql_running) == "Yes"); + sstatus_row.master_server_id = result->get_uint(i_master_server_id); - if (sstatus.slave_io_running == SlaveStatus::SLAVE_IO_YES) + if (sstatus_row.slave_io_running == SlaveStatus::SLAVE_IO_YES && sstatus_row.slave_sql_running) { + nrunning++; // TODO: Fix for multisource replication, check changes to IO_Pos here and save somewhere. - sstatus.master_server_id = result->get_uint(i_master_server_id); - if (sstatus.slave_sql_running) - { - nrunning++; - } } if (all_slaves_status) { - sstatus.name = result->get_string(i_connection_name); + sstatus_row.name = result->get_string(i_connection_name); auto heartbeats = result->get_uint(i_slave_rec_hbs); if (m_n_slave_heartbeats < heartbeats) // TODO: Fix for multisource replication { @@ -214,12 +211,21 @@ bool MariaDBServer::do_show_slave_status(string* errmsg_out) if (!gtid_io_pos.empty() && (using_gtid == "Current_Pos" || using_gtid == "Slave_Pos")) { - sstatus.gtid_io_pos = GtidList::from_string(gtid_io_pos); + sstatus_row.gtid_io_pos = GtidList::from_string(gtid_io_pos); } } - m_slave_status.push_back(sstatus); + slave_status_new.push_back(sstatus_row); } + if (!sstatus_arrays_topology_equal(slave_status_new, m_slave_status)) + { + m_topology_changed = true; + } + + // Always write to m_slave_status. Even if the new status is equal by topology, + // gtid:s etc may have changed. + m_slave_status = std::move(slave_status_new); + if (m_slave_status.empty()) { /** Query returned no rows, replication is not configured */ @@ -308,9 +314,20 @@ bool MariaDBServer::read_server_variables(string* errmsg_out) server_id_parsed = SERVER_ID_UNKNOWN; rval = false; } + if (server_id_parsed != m_server_id) + { + m_server_id = server_id_parsed; + m_topology_changed = true; + } database->server->node_id = server_id_parsed; - m_server_id = server_id_parsed; - m_read_only = result->get_bool(i_ro); + + bool read_only_parsed = result->get_bool(i_ro); + if (read_only_parsed != m_read_only) + { + m_read_only = read_only_parsed; + m_topology_changed = true; + } + if (columns == 3) { int64_t domain_id_parsed = result->get_uint(i_domain); @@ -894,6 +911,38 @@ void MariaDBServer::set_status(uint64_t bits) monitor_set_pending_status(m_server_base, bits); } +/** + * Compare if two slave status arrays are equal. Only compares the parts relevant for building replication + * topology: master server id:s and slave connection io states. + * + * @param lhs Left hand side + * @param rhs Right hand side + * @return True if equal + */ +bool MariaDBServer::sstatus_arrays_topology_equal(const SlaveStatusArray& lhs, const SlaveStatusArray& rhs) +{ + bool rval = true; + if (lhs.size() != rhs.size()) + { + rval = false; + } + else + { + for (size_t i = 0; i < lhs.size(); i++) + { + // It's enough to check just the following two items, as these are used in + // 'build_replication_graph'. + if (lhs[i].slave_io_running != rhs[i].slave_io_running || + lhs[i].master_server_id != rhs[i].master_server_id) + { + rval = false; + break; + } + } + } + return rval; +} + string SlaveStatus::to_string() const { using std::setw; diff --git a/server/modules/monitor/mariadbmon/mariadbserver.hh b/server/modules/monitor/mariadbmon/mariadbserver.hh index 20a0739a3..24ff72420 100644 --- a/server/modules/monitor/mariadbmon/mariadbserver.hh +++ b/server/modules/monitor/mariadbmon/mariadbserver.hh @@ -132,7 +132,7 @@ public: * own the struct, it is not freed (or connection closed) when * a MariaDBServer is destroyed. Can be const on gcc 4.8 */ int m_config_index; /**< What position this server has in the monitor config */ - bool m_print_update_errormsg;/**< Should an update error be printed. */ + version m_version; /**< Server version/type. */ int64_t m_server_id; /**< Value of @@server_id. Valid values are 32bit unsigned. */ bool m_read_only; /**< Value of @@read_only */ @@ -144,9 +144,13 @@ public: * new non-replicated events. */ GtidList m_gtid_current_pos; /**< Gtid of latest event. */ GtidList m_gtid_binlog_pos; /**< Gtid of latest event written to binlog. */ + bool m_topology_changed; /**< Has anything that could affect replication topology changed + * this iteration? Causes: server id, slave connections, + * read-only. */ + NodeData m_node; /**< Replication topology data */ SlaveStatusArray m_slave_status; /**< Data returned from SHOW SLAVE STATUS */ ReplicationSettings m_rpl_settings; /**< Miscellaneous replication related settings */ - NodeData m_node; /**< Replication topology data */ + bool m_print_update_errormsg;/**< Should an update error be printed. */ MariaDBServer(MXS_MONITORED_SERVER* monitored_server, int config_index); @@ -388,6 +392,7 @@ public: private: bool update_slave_status(std::string* errmsg_out = NULL); + static bool sstatus_arrays_topology_equal(const SlaveStatusArray& lhs, const SlaveStatusArray& rhs); }; /**