diff --git a/server/modules/monitor/mariadbmon/cluster_discovery.cc b/server/modules/monitor/mariadbmon/cluster_discovery.cc index 3b43f11e1..a470ce374 100644 --- a/server/modules/monitor/mariadbmon/cluster_discovery.cc +++ b/server/modules/monitor/mariadbmon/cluster_discovery.cc @@ -13,11 +13,17 @@ #include "mariadbmon.hh" #include +#include #include #include "utilities.hh" static int add_slave_to_master(long *slaves_list, int list_size, long node_id); +static bool check_replicate_ignore_table(MXS_MONITORED_SERVER* database); +static bool check_replicate_do_table(MXS_MONITORED_SERVER* database); +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 bool report_version_err = true; /** @@ -138,11 +144,11 @@ MXS_MONITORED_SERVER* MariaDBMonitor::build_mysql51_replication_tree() * This function computes the replication tree from a set of monitored servers and returns the root server * with SERVER_MASTER bit. The tree is computed even for servers in 'maintenance' mode. * - * @param num_servers The number of servers monitored * @return The server at root level with SERVER_MASTER bit */ -MXS_MONITORED_SERVER* MariaDBMonitor::get_replication_tree(int num_servers) +MXS_MONITORED_SERVER* MariaDBMonitor::get_replication_tree() { + const int num_servers = m_servers.size(); MXS_MONITORED_SERVER *ptr; MXS_MONITORED_SERVER *backend; SERVER *current; @@ -172,10 +178,10 @@ MXS_MONITORED_SERVER* MariaDBMonitor::get_replication_tree(int num_servers) /** Either this node doesn't replicate from a master or the master * where it replicates from is not configured to this monitor. */ if (node_id < 1 || - getServerByNodeId(m_monitor_base->monitored_servers, node_id) == NULL) + getServerByNodeId(node_id) == NULL) { MXS_MONITORED_SERVER *find_slave; - find_slave = getSlaveOfNodeId(m_monitor_base->monitored_servers, current->node_id, ACCEPT_DOWN); + find_slave = getSlaveOfNodeId(current->node_id, ACCEPT_DOWN); if (find_slave == NULL) { @@ -202,7 +208,7 @@ MXS_MONITORED_SERVER* MariaDBMonitor::get_replication_tree(int num_servers) root_level = current->depth; m_master = ptr; } - backend = getServerByNodeId(m_monitor_base->monitored_servers, node_id); + backend = getServerByNodeId(node_id); if (backend) { @@ -224,7 +230,7 @@ MXS_MONITORED_SERVER* MariaDBMonitor::get_replication_tree(int num_servers) MXS_MONITORED_SERVER *master_cand; current->depth = depth; - master_cand = getServerByNodeId(m_monitor_base->monitored_servers, current->master_id); + master_cand = getServerByNodeId(current->master_id); if (master_cand && master_cand->server && master_cand->server->node_id > 0) { add_slave_to_master(master_cand->server->slaves, sizeof(master_cand->server->slaves), @@ -310,14 +316,14 @@ static int add_slave_to_master(long *slaves_list, int list_size, long node_id) /** * Fetch a node by node_id * - * @param ptr The list of servers to monitor * @param node_id The server_id to fetch * * @return The server with the required server_id */ -MXS_MONITORED_SERVER* getServerByNodeId(MXS_MONITORED_SERVER *ptr, long node_id) +MXS_MONITORED_SERVER* MariaDBMonitor::getServerByNodeId(long node_id) { SERVER *current; + MXS_MONITORED_SERVER *ptr = m_monitor_base->monitored_servers; while (ptr) { current = ptr->server; @@ -333,14 +339,13 @@ MXS_MONITORED_SERVER* getServerByNodeId(MXS_MONITORED_SERVER *ptr, long node_id) /** * Fetch a slave node from a node_id * - * @param ptr The list of servers to monitor * @param node_id The server_id to fetch * @param slave_down_setting Whether to accept or reject slaves which are down * @return The slave server of this node_id */ -MXS_MONITORED_SERVER* getSlaveOfNodeId(MXS_MONITORED_SERVER *ptr, long node_id, - slave_down_setting_t slave_down_setting) +MXS_MONITORED_SERVER* MariaDBMonitor::getSlaveOfNodeId(long node_id, slave_down_setting_t slave_down_setting) { + MXS_MONITORED_SERVER *ptr = m_monitor_base->monitored_servers; SERVER *current; while (ptr) { @@ -478,15 +483,16 @@ static void visit_node(struct graph_node *node, struct graph_node **stack, * member. Nodes in a group get a positive group ID where the nodes not in a * group get a group ID of 0. */ -void find_graph_cycles(MariaDBMonitor *handle, MXS_MONITORED_SERVER *database, int nservers) +void MariaDBMonitor::find_graph_cycles() { + const int nservers = m_servers.size(); struct graph_node graph[nservers]; struct graph_node *stack[nservers]; int nodes = 0; - for (MXS_MONITORED_SERVER *db = database; db; db = db->next) + for (MXS_MONITORED_SERVER *db = m_monitor_base->monitored_servers; db; db = db->next) { - graph[nodes].info = handle->get_server_info(db); + graph[nodes].info = get_server_info(db); graph[nodes].db = db; graph[nodes].index = graph[nodes].lowest_index = 0; graph[nodes].cycle = 0; @@ -543,7 +549,7 @@ void find_graph_cycles(MariaDBMonitor *handle, MXS_MONITORED_SERVER *database, i monitor_clear_pending_status(graph[i].db, SERVER_SLAVE | SERVER_STALE_SLAVE); } } - else if (handle->detectStaleMaster && cycle == 0 && + else if (m_detect_stale_master && cycle == 0 && graph[i].db->server->status & SERVER_MASTER && (graph[i].db->pending_status & SERVER_MASTER) == 0) { @@ -725,3 +731,222 @@ MariaDBServer* MariaDBMonitor::update_slave_info(MXS_MONITORED_SERVER* server) } return NULL; } + +/** + * Check if the maxscale_schema.replication_heartbeat table is replicated on all + * servers and log a warning if problems were found. + * + * @param monitor Monitor structure + */ +void MariaDBMonitor::check_maxscale_schema_replication() +{ + MXS_MONITORED_SERVER* database = m_monitor_base->monitored_servers; + bool err = false; + + while (database) + { + mxs_connect_result_t rval = mon_ping_or_connect_to_db(m_monitor_base, database); + if (rval == MONITOR_CONN_OK) + { + if (!check_replicate_ignore_table(database) || + !check_replicate_do_table(database) || + !check_replicate_wild_do_table(database) || + !check_replicate_wild_ignore_table(database)) + { + err = true; + } + } + else + { + mon_log_connect_error(database, rval); + } + database = database->next; + } + + if (err) + { + MXS_WARNING("Problems were encountered when checking if '%s' is replicated. Make sure that " + "the table is replicated to all slaves.", HB_TABLE_NAME); + } +} + +/** + * Check if replicate_ignore_table is defined and if maxscale_schema.replication_hearbeat + * table is in the list. + * @param database Server to check + * @return False if the table is not replicated or an error occurred when querying + * the server + */ +static bool check_replicate_ignore_table(MXS_MONITORED_SERVER* database) +{ + MYSQL_RES *result; + bool rval = true; + + if (mxs_mysql_query(database->con, + "show variables like 'replicate_ignore_table'") == 0 && + (result = mysql_store_result(database->con)) && + mysql_num_fields(result) > 1) + { + MYSQL_ROW row; + + while ((row = mysql_fetch_row(result))) + { + if (strlen(row[1]) > 0 && + strcasestr(row[1], HB_TABLE_NAME)) + { + MXS_WARNING("'replicate_ignore_table' is " + "defined on server '%s' and '%s' was found in it. ", + database->server->unique_name, HB_TABLE_NAME); + rval = false; + } + } + + mysql_free_result(result); + } + else + { + MXS_ERROR("Failed to query server %s for " + "'replicate_ignore_table': %s", + database->server->unique_name, + mysql_error(database->con)); + rval = false; + } + return rval; +} + +/** + * Check if replicate_do_table is defined and if maxscale_schema.replication_hearbeat + * table is not in the list. + * @param database Server to check + * @return False if the table is not replicated or an error occurred when querying + * the server + */ +static bool check_replicate_do_table(MXS_MONITORED_SERVER* database) +{ + MYSQL_RES *result; + bool rval = true; + + if (mxs_mysql_query(database->con, + "show variables like 'replicate_do_table'") == 0 && + (result = mysql_store_result(database->con)) && + mysql_num_fields(result) > 1) + { + MYSQL_ROW row; + + while ((row = mysql_fetch_row(result))) + { + if (strlen(row[1]) > 0 && + strcasestr(row[1], HB_TABLE_NAME) == NULL) + { + MXS_WARNING("'replicate_do_table' is " + "defined on server '%s' and '%s' was not found in it. ", + database->server->unique_name, HB_TABLE_NAME); + rval = false; + } + } + mysql_free_result(result); + } + else + { + MXS_ERROR("Failed to query server %s for " + "'replicate_do_table': %s", + database->server->unique_name, + mysql_error(database->con)); + rval = false; + } + return rval; +} + +/** + * Check if replicate_wild_do_table is defined and if it doesn't match + * maxscale_schema.replication_heartbeat. + * @param database Database server + * @return False if the table is not replicated or an error occurred when trying to + * query the server. + */ +static bool check_replicate_wild_do_table(MXS_MONITORED_SERVER* database) +{ + MYSQL_RES *result; + bool rval = true; + + if (mxs_mysql_query(database->con, + "show variables like 'replicate_wild_do_table'") == 0 && + (result = mysql_store_result(database->con)) && + mysql_num_fields(result) > 1) + { + MYSQL_ROW row; + + while ((row = mysql_fetch_row(result))) + { + if (strlen(row[1]) > 0) + { + mxs_pcre2_result_t rc = modutil_mysql_wildcard_match(row[1], HB_TABLE_NAME); + if (rc == MXS_PCRE2_NOMATCH) + { + MXS_WARNING("'replicate_wild_do_table' is " + "defined on server '%s' and '%s' does not match it. ", + database->server->unique_name, + HB_TABLE_NAME); + rval = false; + } + } + } + mysql_free_result(result); + } + else + { + MXS_ERROR("Failed to query server %s for " + "'replicate_wild_do_table': %s", + database->server->unique_name, + mysql_error(database->con)); + rval = false; + } + return rval; +} + +/** + * Check if replicate_wild_ignore_table is defined and if it matches + * maxscale_schema.replication_heartbeat. + * @param database Database server + * @return False if the table is not replicated or an error occurred when trying to + * query the server. + */ +static bool check_replicate_wild_ignore_table(MXS_MONITORED_SERVER* database) +{ + MYSQL_RES *result; + bool rval = true; + + if (mxs_mysql_query(database->con, + "show variables like 'replicate_wild_ignore_table'") == 0 && + (result = mysql_store_result(database->con)) && + mysql_num_fields(result) > 1) + { + MYSQL_ROW row; + + while ((row = mysql_fetch_row(result))) + { + if (strlen(row[1]) > 0) + { + mxs_pcre2_result_t rc = modutil_mysql_wildcard_match(row[1], HB_TABLE_NAME); + if (rc == MXS_PCRE2_MATCH) + { + MXS_WARNING("'replicate_wild_ignore_table' is " + "defined on server '%s' and '%s' matches it. ", + database->server->unique_name, + HB_TABLE_NAME); + rval = false; + } + } + } + mysql_free_result(result); + } + else + { + MXS_ERROR("Failed to query server %s for " + "'replicate_wild_do_table': %s", + database->server->unique_name, + mysql_error(database->con)); + rval = false; + } + return rval; +} diff --git a/server/modules/monitor/mariadbmon/mariadbmon.cc b/server/modules/monitor/mariadbmon/mariadbmon.cc index d073ec7ea..6ecae901b 100644 --- a/server/modules/monitor/mariadbmon/mariadbmon.cc +++ b/server/modules/monitor/mariadbmon/mariadbmon.cc @@ -24,7 +24,7 @@ #include #include #include -#include + #include #include #include @@ -35,9 +35,6 @@ using std::string; static void monitorMain(void *); -void check_maxscale_schema_replication(MXS_MONITOR *monitor); - -static const char* hb_table_name = "maxscale_schema.replication_heartbeat"; // Config parameter names const char * const CN_AUTO_FAILOVER = "auto_failover"; @@ -176,7 +173,7 @@ MariaDBMonitor* MariaDBMonitor::start(MXS_MONITOR *monitor, const MXS_CONFIG_PAR */ bool MariaDBMonitor::load_config_params(const MXS_CONFIG_PARAMETER* params) { - detectStaleMaster = config_get_bool(params, "detect_stale_master"); + m_detect_stale_master = config_get_bool(params, "detect_stale_master"); m_detect_stale_slave = config_get_bool(params, "detect_stale_slave"); m_detect_replication_lag = config_get_bool(params, "detect_replication_lag"); m_detect_multimaster = config_get_bool(params, "multimaster"); @@ -240,7 +237,7 @@ void MariaDBMonitor::diagnostics(DCB *dcb) const dcb_printf(dcb, "Automatic rejoin: %s\n", m_auto_rejoin ? "Enabled" : "Disabled"); dcb_printf(dcb, "MaxScale monitor ID: %lu\n", m_id); dcb_printf(dcb, "Detect replication lag: %s\n", (m_detect_replication_lag) ? "Enabled" : "Disabled"); - dcb_printf(dcb, "Detect stale master: %s\n", (detectStaleMaster == 1) ? + dcb_printf(dcb, "Detect stale master: %s\n", (m_detect_stale_master == 1) ? "Enabled" : "Disabled"); if (m_excluded_servers.size() > 0) { @@ -297,7 +294,7 @@ json_t* MariaDBMonitor::diagnostics_json() const { json_t* rval = json_object(); json_object_set_new(rval, "monitor_id", json_integer(m_id)); - json_object_set_new(rval, "detect_stale_master", json_boolean(detectStaleMaster)); + json_object_set_new(rval, "detect_stale_master", json_boolean(m_detect_stale_master)); json_object_set_new(rval, "detect_stale_slave", json_boolean(m_detect_stale_slave)); json_object_set_new(rval, "detect_replication_lag", json_boolean(m_detect_replication_lag)); json_object_set_new(rval, "multimaster", json_boolean(m_detect_multimaster)); @@ -446,16 +443,11 @@ bool MariaDBMonitor::set_standalone_master(MXS_MONITORED_SERVER *db) void MariaDBMonitor::main_loop() { m_status = MXS_MONITOR_RUNNING; - bool replication_heartbeat; - bool detect_stale_master; MXS_MONITORED_SERVER *root_master = NULL; size_t nrounds = 0; int log_no_master = 1; bool heartbeat_checked = false; - replication_heartbeat = m_detect_replication_lag; - detect_stale_master = detectStaleMaster; - if (mysql_thread_init()) { MXS_ERROR("mysql_thread_init failed in monitor module. Exiting."); @@ -479,7 +471,7 @@ void MariaDBMonitor::main_loop() if (m_detect_replication_lag && !heartbeat_checked) { - check_maxscale_schema_replication(m_monitor_base); + check_maxscale_schema_replication(); heartbeat_checked = true; } @@ -532,7 +524,7 @@ void MariaDBMonitor::main_loop() /* 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, detect_stale_master); + update_server_states(*iter, root_master, m_detect_stale_master); } /** Now that all servers have their status correctly set, we can check @@ -593,10 +585,8 @@ void MariaDBMonitor::main_loop() log_master_changes(root_master, &log_no_master); /* Generate the replication heartbeat event by performing an update */ - if (replication_heartbeat && - root_master && - (SERVER_IS_MASTER(root_master->server) || - SERVER_IS_RELAY_SERVER(root_master->server))) + if (m_detect_replication_lag && root_master && + (SERVER_IS_MASTER(root_master->server) || SERVER_IS_RELAY_SERVER(root_master->server))) { measure_replication_lag(root_master); } @@ -709,7 +699,7 @@ void MariaDBMonitor::find_root_master(MXS_MONITORED_SERVER** root_master) } else { - *root_master = get_replication_tree(num_servers); + *root_master = get_replication_tree(); } } @@ -718,7 +708,7 @@ void MariaDBMonitor::find_root_master(MXS_MONITORED_SERVER** root_master) /** Find all the master server cycles in the cluster graph. If multiple masters are found, the servers with the read_only variable set to ON will be assigned the slave status. */ - find_graph_cycles(this, m_monitor_base->monitored_servers, num_servers); + find_graph_cycles(); } } @@ -779,8 +769,8 @@ void MariaDBMonitor::assign_relay_master(MariaDBServer& serv_info) { MXS_MONITORED_SERVER* ptr = serv_info.server_base; if (ptr->server->node_id > 0 && ptr->server->master_id > 0 && - getSlaveOfNodeId(m_monitor_base->monitored_servers, ptr->server->node_id, REJECT_DOWN) && - getServerByNodeId(m_monitor_base->monitored_servers, ptr->server->master_id) && + getSlaveOfNodeId(ptr->server->node_id, REJECT_DOWN) && + getServerByNodeId(ptr->server->master_id) && (!m_detect_multimaster || serv_info.group == 0)) { /** This server is both a slave and a master i.e. a relay master */ @@ -1235,224 +1225,6 @@ void MariaDBMonitor::set_slave_heartbeat(MXS_MONITORED_SERVER *database) } } -/** - * Check if replicate_ignore_table is defined and if maxscale_schema.replication_hearbeat - * table is in the list. - * @param database Server to check - * @return False if the table is not replicated or an error occurred when querying - * the server - */ -bool check_replicate_ignore_table(MXS_MONITORED_SERVER* database) -{ - MYSQL_RES *result; - bool rval = true; - - if (mxs_mysql_query(database->con, - "show variables like 'replicate_ignore_table'") == 0 && - (result = mysql_store_result(database->con)) && - mysql_num_fields(result) > 1) - { - MYSQL_ROW row; - - while ((row = mysql_fetch_row(result))) - { - if (strlen(row[1]) > 0 && - strcasestr(row[1], hb_table_name)) - { - MXS_WARNING("'replicate_ignore_table' is " - "defined on server '%s' and '%s' was found in it. ", - database->server->unique_name, hb_table_name); - rval = false; - } - } - - mysql_free_result(result); - } - else - { - MXS_ERROR("Failed to query server %s for " - "'replicate_ignore_table': %s", - database->server->unique_name, - mysql_error(database->con)); - rval = false; - } - return rval; -} - -/** - * Check if replicate_do_table is defined and if maxscale_schema.replication_hearbeat - * table is not in the list. - * @param database Server to check - * @return False if the table is not replicated or an error occurred when querying - * the server - */ -bool check_replicate_do_table(MXS_MONITORED_SERVER* database) -{ - MYSQL_RES *result; - bool rval = true; - - if (mxs_mysql_query(database->con, - "show variables like 'replicate_do_table'") == 0 && - (result = mysql_store_result(database->con)) && - mysql_num_fields(result) > 1) - { - MYSQL_ROW row; - - while ((row = mysql_fetch_row(result))) - { - if (strlen(row[1]) > 0 && - strcasestr(row[1], hb_table_name) == NULL) - { - MXS_WARNING("'replicate_do_table' is " - "defined on server '%s' and '%s' was not found in it. ", - database->server->unique_name, hb_table_name); - rval = false; - } - } - mysql_free_result(result); - } - else - { - MXS_ERROR("Failed to query server %s for " - "'replicate_do_table': %s", - database->server->unique_name, - mysql_error(database->con)); - rval = false; - } - return rval; -} - -/** - * Check if replicate_wild_do_table is defined and if it doesn't match - * maxscale_schema.replication_heartbeat. - * @param database Database server - * @return False if the table is not replicated or an error occurred when trying to - * query the server. - */ -bool check_replicate_wild_do_table(MXS_MONITORED_SERVER* database) -{ - MYSQL_RES *result; - bool rval = true; - - if (mxs_mysql_query(database->con, - "show variables like 'replicate_wild_do_table'") == 0 && - (result = mysql_store_result(database->con)) && - mysql_num_fields(result) > 1) - { - MYSQL_ROW row; - - while ((row = mysql_fetch_row(result))) - { - if (strlen(row[1]) > 0) - { - mxs_pcre2_result_t rc = modutil_mysql_wildcard_match(row[1], hb_table_name); - if (rc == MXS_PCRE2_NOMATCH) - { - MXS_WARNING("'replicate_wild_do_table' is " - "defined on server '%s' and '%s' does not match it. ", - database->server->unique_name, - hb_table_name); - rval = false; - } - } - } - mysql_free_result(result); - } - else - { - MXS_ERROR("Failed to query server %s for " - "'replicate_wild_do_table': %s", - database->server->unique_name, - mysql_error(database->con)); - rval = false; - } - return rval; -} - -/** - * Check if replicate_wild_ignore_table is defined and if it matches - * maxscale_schema.replication_heartbeat. - * @param database Database server - * @return False if the table is not replicated or an error occurred when trying to - * query the server. - */ -bool check_replicate_wild_ignore_table(MXS_MONITORED_SERVER* database) -{ - MYSQL_RES *result; - bool rval = true; - - if (mxs_mysql_query(database->con, - "show variables like 'replicate_wild_ignore_table'") == 0 && - (result = mysql_store_result(database->con)) && - mysql_num_fields(result) > 1) - { - MYSQL_ROW row; - - while ((row = mysql_fetch_row(result))) - { - if (strlen(row[1]) > 0) - { - mxs_pcre2_result_t rc = modutil_mysql_wildcard_match(row[1], hb_table_name); - if (rc == MXS_PCRE2_MATCH) - { - MXS_WARNING("'replicate_wild_ignore_table' is " - "defined on server '%s' and '%s' matches it. ", - database->server->unique_name, - hb_table_name); - rval = false; - } - } - } - mysql_free_result(result); - } - else - { - MXS_ERROR("Failed to query server %s for " - "'replicate_wild_do_table': %s", - database->server->unique_name, - mysql_error(database->con)); - rval = false; - } - return rval; -} - -/** - * Check if the maxscale_schema.replication_heartbeat table is replicated on all - * servers and log a warning if problems were found. - * @param monitor Monitor structure - */ -void check_maxscale_schema_replication(MXS_MONITOR *monitor) -{ - MXS_MONITORED_SERVER* database = monitor->monitored_servers; - bool err = false; - - while (database) - { - mxs_connect_result_t rval = mon_ping_or_connect_to_db(monitor, database); - if (rval == MONITOR_CONN_OK) - { - if (!check_replicate_ignore_table(database) || - !check_replicate_do_table(database) || - !check_replicate_wild_do_table(database) || - !check_replicate_wild_ignore_table(database)) - { - err = true; - } - } - else - { - mon_log_connect_error(database, rval); - } - database = database->next; - } - - if (err) - { - MXS_WARNING("Problems were encountered when checking if '%s' is replicated. Make sure that " - "the table is replicated to all slaves.", hb_table_name); - } -} - /** * Set a monitor config parameter to "false". The effect persists over stopMonitor/startMonitor but not * MaxScale restart. Only use on boolean config settings. diff --git a/server/modules/monitor/mariadbmon/mariadbmon.hh b/server/modules/monitor/mariadbmon/mariadbmon.hh index 634f0b1d5..cc0bc7892 100644 --- a/server/modules/monitor/mariadbmon/mariadbmon.hh +++ b/server/modules/monitor/mariadbmon/mariadbmon.hh @@ -25,8 +25,6 @@ #include "mariadbserver.hh" #include "utilities.hh" -using std::string; - extern const int PORT_UNKNOWN; extern const char * const CN_AUTO_FAILOVER; @@ -37,18 +35,8 @@ typedef std::tr1::unordered_map ServerInf // Server container, owns the server objects. typedef std::vector ServerContainer; // TODO: Rename/get rid of ServerVector typedef! -enum slave_down_setting_t -{ - ACCEPT_DOWN, - REJECT_DOWN -}; - // TODO: Most of following should be class methods void print_redirect_errors(MXS_MONITORED_SERVER* first_server, const ServerVector& servers, json_t** err_out); -MXS_MONITORED_SERVER* getServerByNodeId(MXS_MONITORED_SERVER *, long); -MXS_MONITORED_SERVER* getSlaveOfNodeId(MXS_MONITORED_SERVER *, long, slave_down_setting_t); - -void find_graph_cycles(MariaDBMonitor *handle, MXS_MONITORED_SERVER *database, int nservers); // MariaDB Monitor instance data class MariaDBMonitor @@ -146,8 +134,6 @@ public: */ const MariaDBServer* get_server_info(const MXS_MONITORED_SERVER* db) const; - bool detectStaleMaster; /**< Monitor flag for MySQL replication Stale Master detection */ - private: MXS_MONITOR* m_monitor_base; /**< Generic monitor object */ THREAD m_thread; /**< Monitor thread */ @@ -159,12 +145,13 @@ private: // Values updated by monitor int64_t m_master_gtid_domain; /**< Gtid domain currently used by the master */ - string m_external_master_host; /**< External master host, for fail/switchover */ + std::string m_external_master_host; /**< External master host, for fail/switchover */ int m_external_master_port; /**< External master port */ MXS_MONITORED_SERVER *m_master; /**< Master server for MySQL Master/Slave replication */ // Replication topology detection settings bool m_mysql51_replication; /**< Use MySQL 5.1 replication */ + bool m_detect_stale_master; /**< Monitor flag for MySQL replication Stale Master detection */ bool m_detect_stale_slave; /**< Monitor flag for MySQL replication Stale Slave detection */ bool m_detect_multimaster; /**< Detect and handle multi-master topologies */ bool m_ignore_external_masters; /**< Ignore masters outside of the monitor configuration */ @@ -173,8 +160,8 @@ private: bool m_warn_set_standalone_master; /**< Log a warning when setting standalone master */ // Failover, switchover and rejoin settings - string m_replication_user; /**< Replication user for CHANGE MASTER TO-commands */ - string m_replication_password; /**< Replication password for CHANGE MASTER TO-commands */ + std::string m_replication_user; /**< Replication user for CHANGE MASTER TO-commands */ + std::string m_replication_password; /**< Replication password for CHANGE MASTER TO-commands */ int m_failcount; /**< How many monitoring cycles master must be down before auto-failover * begins */ uint32_t m_failover_timeout; /**< Timeout in seconds for the master failover */ @@ -187,10 +174,16 @@ private: ServerVector m_excluded_servers; /**< Servers banned for master promotion during auto-failover. */ // Other settings - string m_script; /**< Script to call when state changes occur on servers */ + std::string m_script; /**< Script to call when state changes occur on servers */ uint64_t m_events; /**< enabled events */ bool m_detect_replication_lag; /**< Monitor flag for MySQL replication heartbeat */ + enum slave_down_setting_t + { + ACCEPT_DOWN, + REJECT_DOWN + }; + MariaDBMonitor(MXS_MONITOR* monitor_base); ~MariaDBMonitor(); bool load_config_params(const MXS_CONFIG_PARAMETER* params); @@ -214,7 +207,7 @@ private: bool standalone_master_required(MXS_MONITORED_SERVER *db); bool set_standalone_master(MXS_MONITORED_SERVER *db); bool failover_not_possible(); - string generate_change_master_cmd(const string& master_host, int master_port); + std::string generate_change_master_cmd(const std::string& master_host, int master_port); int redirect_slaves(MXS_MONITORED_SERVER* new_master, const ServerVector& slaves, ServerVector* redirected_slaves); bool set_replication_credentials(const MXS_CONFIG_PARAMETER* params); @@ -226,7 +219,7 @@ private: void set_master_heartbeat(MXS_MONITORED_SERVER *); void set_slave_heartbeat(MXS_MONITORED_SERVER *); MXS_MONITORED_SERVER* build_mysql51_replication_tree(); - MXS_MONITORED_SERVER* get_replication_tree(int num_servers); + MXS_MONITORED_SERVER* get_replication_tree(); void monitor_mysql_db(MariaDBServer *serv_info); bool do_switchover(MXS_MONITORED_SERVER* current_master, MXS_MONITORED_SERVER* new_master, json_t** err_out); @@ -254,4 +247,8 @@ private: void handle_auto_failover(bool* failover_performed); void measure_replication_lag(MXS_MONITORED_SERVER* root_master); void handle_auto_rejoin(); + void find_graph_cycles(); + void check_maxscale_schema_replication(); + MXS_MONITORED_SERVER* getServerByNodeId(long); + MXS_MONITORED_SERVER* getSlaveOfNodeId(long, slave_down_setting_t); };