diff --git a/server/modules/monitor/mariadbmon/cluster_discovery.cc b/server/modules/monitor/mariadbmon/cluster_discovery.cc index f6ff8f91b..8cc9075d4 100644 --- a/server/modules/monitor/mariadbmon/cluster_discovery.cc +++ b/server/modules/monitor/mariadbmon/cluster_discovery.cc @@ -654,7 +654,7 @@ void MariaDBMonitor::assign_slave_and_relay_master(MariaDBServer* start_node) } // If the node is a binlog relay, remove any slave bits that may have been set. // Relay master bit can stay. - if (parent->m_version == MariaDBServer::version::BINLOG_ROUTER) + if (parent->m_srv_type == MariaDBServer::server_type::BINLOG_ROUTER) { parent->clear_status(SERVER_SLAVE); } diff --git a/server/modules/monitor/mariadbmon/cluster_manipulation.cc b/server/modules/monitor/mariadbmon/cluster_manipulation.cc index a57e53d46..b9c3a9f16 100644 --- a/server/modules/monitor/mariadbmon/cluster_manipulation.cc +++ b/server/modules/monitor/mariadbmon/cluster_manipulation.cc @@ -1488,8 +1488,7 @@ void MariaDBMonitor::check_cluster_operations_support() { // Need to accept unknown versions here. Otherwise servers which are down when the monitor starts // would deactivate failover. - if (server->m_version != MariaDBServer::version::UNKNOWN - && server->m_version != MariaDBServer::version::MARIADB_100) + if (server->m_srv_type != MariaDBServer::server_type::UNKNOWN && !server->m_capabilities.gtid) { supported = false; auto reason = string_printf("The version of %s (%s) is not supported. Failover/switchover " @@ -1704,7 +1703,7 @@ void MariaDBMonitor::enforce_read_only_on_slaves() for (MariaDBServer* server : m_servers) { if (server->is_slave() && !server->is_read_only() - && (server->m_version != MariaDBServer::version::BINLOG_ROUTER)) + && (server->m_srv_type != MariaDBServer::server_type::BINLOG_ROUTER)) { MYSQL* conn = server->m_server_base->con; if (mxs_mysql_query(conn, QUERY) == 0) diff --git a/server/modules/monitor/mariadbmon/mariadbmon.cc b/server/modules/monitor/mariadbmon/mariadbmon.cc index ecad99d1c..4d238f99f 100644 --- a/server/modules/monitor/mariadbmon/mariadbmon.cc +++ b/server/modules/monitor/mariadbmon/mariadbmon.cc @@ -357,10 +357,8 @@ void MariaDBMonitor::update_server(MariaDBServer* server) server->update_server_version(); } - auto server_vrs = server->m_version; - if (server_vrs == MariaDBServer::version::MARIADB_MYSQL_55 - || server_vrs == MariaDBServer::version::MARIADB_100 - || server_vrs == MariaDBServer::version::BINLOG_ROUTER) + if (server->m_capabilities.basic_support + || server->m_srv_type == MariaDBServer::server_type::BINLOG_ROUTER) { // Check permissions if permissions failed last time or if this is a new connection. if (server->had_status(SERVER_AUTH_ERROR) || conn_status == MONITOR_CONN_NEWCONN_OK) diff --git a/server/modules/monitor/mariadbmon/mariadbserver.cc b/server/modules/monitor/mariadbmon/mariadbserver.cc index a96c35e1e..878cd364a 100644 --- a/server/modules/monitor/mariadbmon/mariadbserver.cc +++ b/server/modules/monitor/mariadbmon/mariadbserver.cc @@ -218,21 +218,20 @@ bool MariaDBServer::do_show_slave_status(string* errmsg_out) unsigned int columns = 0; string query; bool all_slaves_status = false; - switch (m_version) + if (m_capabilities.gtid || m_srv_type == server_type::BINLOG_ROUTER) { - case version::MARIADB_100: - case version::BINLOG_ROUTER: + // Versions with gtid also support the extended slave status query. columns = 42; all_slaves_status = true; - query = "SHOW ALL SLAVES STATUS"; - break; - - case version::MARIADB_MYSQL_55: + query = "SHOW ALL SLAVES STATUS;"; + } + else if (m_capabilities.basic_support) + { columns = 40; - query = "SHOW SLAVE STATUS"; - break; - - default: + query = "SHOW SLAVE STATUS;"; + } + else + { mxb_assert(!true); // This method should not be called for versions < 5.5 return false; } @@ -432,15 +431,10 @@ bool MariaDBServer::update_replication_settings(std::string* errmsg_out) bool MariaDBServer::read_server_variables(string* errmsg_out) { - MXS_MONITORED_SERVER* database = m_server_base; - string query = "SELECT @@global.server_id, @@read_only;"; - int columns = 2; - if (m_version == version::MARIADB_100) - { - query.erase(query.end() - 1); - query += ", @@global.gtid_domain_id;"; - columns = 3; - } + const string query_no_gtid = "SELECT @@global.server_id, @@read_only;"; + const string query_with_gtid = "SELECT @@global.server_id, @@read_only, @@global.gtid_domain_id;"; + const bool use_gtid = m_capabilities.gtid; + const string& query = use_gtid ? query_with_gtid : query_no_gtid; int i_id = 0; int i_ro = 1; @@ -461,7 +455,7 @@ bool MariaDBServer::read_server_variables(string* errmsg_out) m_server_id = server_id_parsed; m_topology_changed = true; } - database->server->node_id = server_id_parsed; + m_server_base->server->node_id = server_id_parsed; bool read_only_parsed = result->get_bool(i_ro); if (read_only_parsed != m_read_only) @@ -470,7 +464,7 @@ bool MariaDBServer::read_server_variables(string* errmsg_out) m_topology_changed = true; } - if (columns == 3) + if (use_gtid) { int64_t domain_id_parsed = result->get_uint(i_domain); if (domain_id_parsed < 0) // Same here. @@ -818,26 +812,23 @@ void MariaDBServer::monitor_server() string errmsg; bool query_ok = false; /* Query different things depending on server version/type. */ - switch (m_version) + if (m_srv_type == server_type::BINLOG_ROUTER) { - case version::MARIADB_MYSQL_55: - query_ok = read_server_variables(&errmsg) && update_slave_status(&errmsg); - break; - - case version::MARIADB_100: - query_ok = read_server_variables(&errmsg) && update_gtids(&errmsg) - && update_slave_status(&errmsg); - break; - - case version::BINLOG_ROUTER: // TODO: Add special version of server variable query. query_ok = update_slave_status(&errmsg); - break; - - default: - // Do not update unknown versions. + } + else if (m_capabilities.basic_support) + { + query_ok = read_server_variables(&errmsg) && update_slave_status(&errmsg); + if (query_ok && m_capabilities.gtid) + { + query_ok = update_gtids(&errmsg); + } + } + else + { + // Not a binlog server and no normal support, don't update. query_ok = true; - break; } if (query_ok) @@ -875,7 +866,7 @@ bool MariaDBServer::update_slave_status(string* errmsg_out) void MariaDBServer::update_server_version() { - m_version = version::UNKNOWN; + m_srv_type = server_type::UNKNOWN; auto conn = m_server_base->con; auto srv = m_server_base->server; @@ -888,28 +879,43 @@ void MariaDBServer::update_server_version() if (mxs_mysql_query(conn, "SELECT @@maxscale_version") == 0 && (result = mysql_store_result(conn)) != NULL) { - m_version = version::BINLOG_ROUTER; + m_srv_type = server_type::BINLOG_ROUTER; mysql_free_result(result); } else { - /* Not a binlog server, check version number. */ - uint64_t version_num = server_get_version(srv); - if (version_num >= 100000 && srv->server_type == SERVER_TYPE_MARIADB) + /* Not a binlog server, check version number and supported features. */ + m_srv_type = server_type::NORMAL; + m_capabilities = Capabilities(); + SERVER_VERSION decoded = {0, 0, 0}; + server_decode_version(server_get_version(srv), &decoded); + auto major = decoded.major; + auto minor = decoded.minor; + auto patch = decoded.patch; + // MariaDB/MySQL 5.5 is the oldest supported version. MySQL 6 and later are treated as 5.5. + if ((major == 5 && minor >= 5) || major > 5) { - m_version = version::MARIADB_100; - } - else if (version_num >= 5 * 10000 + 5 * 100) - { - m_version = version::MARIADB_MYSQL_55; + m_capabilities.basic_support = true; + // For more specific features, at least MariaDB 10.X is needed. + if (srv->server_type == SERVER_TYPE_MARIADB && major >= 10) + { + // 10.0.2 or 10.1.X or greater than 10 + if (((minor == 0 && patch >= 2) || minor >= 1) || major > 10) + { + m_capabilities.gtid = true; + } + // 10.1.2 (10.1.1 has limited support, not enough) or 10.2.X or greater than 10 + if (((minor == 1 && patch >= 2) || minor >= 2) || major > 10) + { + m_capabilities.max_statement_time = true; + } + } } else { - m_version = version::OLD; - MXS_ERROR("MariaDB/MySQL version of server '%s' is less than 5.5, which is not supported. " - "The server is ignored by the monitor. Server version: '%s'.", - name(), - srv->version_string); + MXS_ERROR("MariaDB/MySQL version of %s is less than 5.5, which is not supported. " + "The server is ignored by the monitor. Server version string: '%s'.", + name(), srv->version_string); } } } diff --git a/server/modules/monitor/mariadbmon/mariadbserver.hh b/server/modules/monitor/mariadbmon/mariadbserver.hh index 6ec7eca12..374d72f76 100644 --- a/server/modules/monitor/mariadbmon/mariadbserver.hh +++ b/server/modules/monitor/mariadbmon/mariadbserver.hh @@ -72,14 +72,10 @@ struct NodeData class MariaDBServer { public: - enum class version + enum class server_type { UNKNOWN, /* Totally unknown. Server has not been connected to yet. */ - OLD, /* Anything older than 5.5. These are no longer supported by the monitor. */ - MARIADB_MYSQL_55, /* MariaDB 5.5 series or MySQL 5.5 and later. Does not have gtid (on MariaDB) so - * all gtid-related features (failover etc.) are disabled. */ - MARIADB_100, /* MariaDB 10.0 and greater. In practice though, 10.0.2 or greater is assumed. - * All monitor features are on. */ + NORMAL, /* A normal MariaDB/MySQL server, possibly supported. */ BINLOG_ROUTER /* MaxScale binlog server. Requires special handling. */ }; @@ -89,6 +85,15 @@ public: BINLOG_OFF }; + // Class which encapsulates server capabilities depending on its version. + class Capabilities + { + public: + bool basic_support = false; // Is the server version supported by the monitor at all? + bool gtid = false; // Supports MariaDB gtid? Required for failover etc. + bool max_statement_time = false; // Supports max_statement_time? + }; + // This class groups some miscellaneous replication related settings together. class ReplicationSettings { @@ -104,7 +109,9 @@ public: /* What position this server has in the monitor config? Used for tiebreaking between servers. */ int m_config_index = 0; - version m_version = version::UNKNOWN; /* Server version/type. */ + server_type m_srv_type = server_type::UNKNOWN; /* Server type. */ + Capabilities m_capabilities; /* Server capabilities */ + int64_t m_server_id = SERVER_ID_UNKNOWN; /* Value of @@server_id. Valid values are * 32bit unsigned. */ int64_t m_gtid_domain_id = GTID_DOMAIN_UNKNOWN; /* The value of gtid_domain_id, the domain which is used