diff --git a/include/MySQL_Monitor.hpp b/include/MySQL_Monitor.hpp index 32765f49cc..08901f5616 100644 --- a/include/MySQL_Monitor.hpp +++ b/include/MySQL_Monitor.hpp @@ -448,6 +448,7 @@ class MySQL_Monitor { static void trigger_dns_cache_update(); void process_discovered_topology(const std::string& originating_server_hostname, const vector& discovered_servers, int reader_hostgroup); + bool is_aws_rds_multi_az_db_cluster_topology(const std::vector& discovered_servers); private: std::vector *tables_defs_monitor; diff --git a/lib/MySQL_Monitor.cpp b/lib/MySQL_Monitor.cpp index 4d5d9bc95f..a0cd601221 100644 --- a/lib/MySQL_Monitor.cpp +++ b/lib/MySQL_Monitor.cpp @@ -3353,6 +3353,35 @@ void MySQL_Monitor::process_discovered_topology(const std::string& originating_s } } +/** +* @brief Check if a list of servers is matching the description of an AWS RDS Multi-AZ DB Cluster. +* @details This method takes a vector of discovered servers and checks that there are exactly three which are named "instance-[1|2|3]" respectively, as expected on an AWS RDS Multi-AZ DB Cluster. +* @param discovered_servers A vector of servers discovered when querying the cluster's topology. +* @return Returns 'true' if all conditions are met and 'false' otherwise. +*/ +bool MySQL_Monitor::is_aws_rds_multi_az_db_cluster_topology(const std::vector& discovered_servers) { + if (discovered_servers.size() != 3) { + return false; + } + + const std::vector instance_names = {"-instance-1", "-instance-2", "-instance-3"}; + int identified_hosts = 0; + for (const std::string& instance_str : instance_names) { + for (MYSQL_ROW server : discovered_servers) { + if (server[2] == NULL || (server[2][0] == '\0')) { + continue; + } + + std::string current_discovered_hostname = server[2]; + if (current_discovered_hostname.find(instance_str) != std::string::npos) { + ++identified_hosts; + break; + } + } + } + return (identified_hosts == 3); +} + void * MySQL_Monitor::monitor_read_only() { mysql_close(mysql_init(NULL)); // initialize the MySQL Thread (note: this is not a real thread, just the structures associated with it) @@ -3367,9 +3396,9 @@ void * MySQL_Monitor::monitor_read_only() { unsigned long long t2; unsigned long long next_loop_at=0; int topology_loop = 0; - int topology_loop_max = mysql_thread___monitor_aws_rds_topology_discovery_interval; while (GloMyMon->shutdown==false && mysql_thread___monitor_enabled==true) { + int topology_loop_max = mysql_thread___monitor_aws_rds_topology_discovery_interval; bool do_discovery_check = false; unsigned int glover; @@ -3404,11 +3433,13 @@ void * MySQL_Monitor::monitor_read_only() { goto __end_monitor_read_only_loop; } - if (topology_loop >= topology_loop_max) { - do_discovery_check = true; - topology_loop = 0; + if (topology_loop_max > 0) { // if the discovery interval is set to zero, do not query for the topology + if (topology_loop >= topology_loop_max) { + do_discovery_check = true; + topology_loop = 0; + } + topology_loop += 1; } - topology_loop += 1; // resultset must be initialized before calling monitor_read_only_async monitor_read_only_async(resultset, do_discovery_check); @@ -7386,8 +7417,8 @@ VALGRIND_ENABLE_ERROR_REPORTING; discovered_servers.push_back(row); } - // Process the discovered servers and add them to 'runtime_mysql_servers' - if (!discovered_servers.empty()) { + // Process the discovered servers and add them to 'runtime_mysql_servers' (process only for AWS RDS Multi-AZ DB Clusters) + if (!discovered_servers.empty() && is_aws_rds_multi_az_db_cluster_topology(discovered_servers)) { process_discovered_topology(originating_server_hostname, discovered_servers, mmsd->reader_hostgroup); } } else { diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index 8d2d3e7e21..4df3d97429 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -985,7 +985,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() { variables.monitor_ping_interval=8000; variables.monitor_ping_max_failures=3; variables.monitor_ping_timeout=1000; - variables.monitor_aws_rds_topology_discovery_interval=1000; + variables.monitor_aws_rds_topology_discovery_interval=0; variables.monitor_read_only_interval=1000; variables.monitor_read_only_timeout=800; variables.monitor_read_only_max_timeout_count=3; @@ -2153,7 +2153,7 @@ char ** MySQL_Threads_Handler::get_variables_list() { VariablesPointers_int["monitor_ping_timeout"] = make_tuple(&variables.monitor_ping_timeout, 100, 600*1000, false); VariablesPointers_int["monitor_ping_max_failures"] = make_tuple(&variables.monitor_ping_max_failures, 1, 1000*1000, false); - VariablesPointers_int["monitor_aws_rds_topology_discovery_interval"] = make_tuple(&variables.monitor_aws_rds_topology_discovery_interval, 1, 100000, false); + VariablesPointers_int["monitor_aws_rds_topology_discovery_interval"] = make_tuple(&variables.monitor_aws_rds_topology_discovery_interval, 0, 100000, false); VariablesPointers_int["monitor_read_only_interval"] = make_tuple(&variables.monitor_read_only_interval, 100, 7*24*3600*1000, false); VariablesPointers_int["monitor_read_only_timeout"] = make_tuple(&variables.monitor_read_only_timeout, 100, 600*1000, false); VariablesPointers_int["monitor_read_only_max_timeout_count"] = make_tuple(&variables.monitor_read_only_max_timeout_count, 1, 1000*1000, false);