diff --git a/server/modules/monitor/mariadbmon/CMakeLists.txt b/server/modules/monitor/mariadbmon/CMakeLists.txt index f2ffc3cb4..0b54763e2 100644 --- a/server/modules/monitor/mariadbmon/CMakeLists.txt +++ b/server/modules/monitor/mariadbmon/CMakeLists.txt @@ -1,4 +1,5 @@ -add_library(mariadbmon SHARED mariadbmon.cc utilities.cc cluster_manipulation.cc cluster_discovery.cc) +add_library(mariadbmon SHARED mariadbmon.cc mariadbserver.cc cluster_manipulation.cc cluster_discovery.cc + utilities.cc) target_link_libraries(mariadbmon maxscale-common) add_dependencies(mariadbmon pcre2) set_target_properties(mariadbmon PROPERTIES VERSION "1.4.0") diff --git a/server/modules/monitor/mariadbmon/cluster_discovery.cc b/server/modules/monitor/mariadbmon/cluster_discovery.cc index b75760adf..881b6b73a 100644 --- a/server/modules/monitor/mariadbmon/cluster_discovery.cc +++ b/server/modules/monitor/mariadbmon/cluster_discovery.cc @@ -14,6 +14,7 @@ #include "mariadbmon.hh" #include #include +#include "utilities.hh" static int add_slave_to_master(long *slaves_list, int list_size, long node_id); static void read_server_variables(MariaDBServer* serv_info); diff --git a/server/modules/monitor/mariadbmon/cluster_manipulation.cc b/server/modules/monitor/mariadbmon/cluster_manipulation.cc index a533242e0..fc2d4584d 100644 --- a/server/modules/monitor/mariadbmon/cluster_manipulation.cc +++ b/server/modules/monitor/mariadbmon/cluster_manipulation.cc @@ -17,6 +17,7 @@ #include #include #include +#include "utilities.hh" bool MariaDBMonitor::manual_switchover(MXS_MONITORED_SERVER* new_master, MXS_MONITORED_SERVER* given_current_master, @@ -982,14 +983,14 @@ bool MariaDBMonitor::switchover_wait_slave_catchup(MXS_MONITORED_SERVER* slave, // Determine a reasonable timeout for the MASTER_GTID_WAIT-function depending on the // backend_read_timeout setting (should be >= 1) and time remaining. double loop_timeout = double(read_timeout) - 0.5; - string cmd = generate_master_gtid_wait_cmd(gtid, loop_timeout); + string cmd = gtid.generate_master_gtid_wait_cmd(loop_timeout); while (seconds_remaining > 0 && !gtid_reached && !error) { if (loop_timeout > seconds_remaining) { // For the last iteration, change the wait timeout. - cmd = generate_master_gtid_wait_cmd(gtid, seconds_remaining); + cmd = gtid.generate_master_gtid_wait_cmd(seconds_remaining); } seconds_remaining -= loop_timeout; @@ -1698,4 +1699,4 @@ bool MariaDBMonitor::slave_receiving_events() } } return received_event; -} \ No newline at end of file +} diff --git a/server/modules/monitor/mariadbmon/mariadbmon.hh b/server/modules/monitor/mariadbmon/mariadbmon.hh index 825f40fe1..49238b8cd 100644 --- a/server/modules/monitor/mariadbmon/mariadbmon.hh +++ b/server/modules/monitor/mariadbmon/mariadbmon.hh @@ -22,6 +22,7 @@ #include #include +#include "mariadbserver.hh" #include "utilities.hh" using std::string; diff --git a/server/modules/monitor/mariadbmon/mariadbserver.cc b/server/modules/monitor/mariadbmon/mariadbserver.cc new file mode 100644 index 000000000..108ba5b8e --- /dev/null +++ b/server/modules/monitor/mariadbmon/mariadbserver.cc @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2018 MariaDB Corporation Ab + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file and at www.mariadb.com/bsl11. + * + * Change Date: 2020-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2 or later of the General + * Public License. + */ + +#include "mariadbserver.hh" + +#include +#include + +#include "utilities.hh" + +Gtid::Gtid() + : domain(0) + , server_id(SERVER_ID_UNKNOWN) + , sequence(0) +{} + +Gtid::Gtid(const char* str, int64_t search_domain) + : domain(0) + , server_id(SERVER_ID_UNKNOWN) + , sequence(0) +{ + // Autoselect only allowed with one triplet + ss_dassert(search_domain >= 0 || strchr(str, ',') == NULL); + parse_triplet(str); + if (search_domain >= 0 && domain != search_domain) + { + // Search for the correct triplet. + bool found = false; + for (const char* next_triplet = strchr(str, ','); + next_triplet != NULL && !found; + next_triplet = strchr(next_triplet, ',')) + { + parse_triplet(++next_triplet); + if (domain == search_domain) + { + found = true; + } + } + ss_dassert(found); + } +} + +bool Gtid::operator == (const Gtid& rhs) const +{ + return domain == rhs.domain && + server_id != SERVER_ID_UNKNOWN && server_id == rhs.server_id && + sequence == rhs.sequence; +} + +string Gtid::to_string() const +{ + std::stringstream ss; + if (server_id != SERVER_ID_UNKNOWN) + { + ss << domain << "-" << server_id << "-" << sequence; + } + return ss.str(); +} + +void Gtid::parse_triplet(const char* str) +{ + ss_debug(int rv = ) sscanf(str, "%" PRIu32 "-%" PRId64 "-%" PRIu64, &domain, &server_id, &sequence); + ss_dassert(rv == 3); +} + +string Gtid::generate_master_gtid_wait_cmd(double timeout) const +{ + std::stringstream query_ss; + query_ss << "SELECT MASTER_GTID_WAIT(\"" << to_string() << "\", " << timeout << ");"; + return query_ss.str(); +} + +SlaveStatusInfo::SlaveStatusInfo() + : master_server_id(SERVER_ID_UNKNOWN) + , master_port(0) + , slave_io_running(false) + , slave_sql_running(false) + , read_master_log_pos(0) +{} + +MariaDBServer::MariaDBServer(MXS_MONITORED_SERVER* monitored_server) + : server_base(monitored_server) + , version(MYSQL_SERVER_VERSION_51) + , server_id(SERVER_ID_UNKNOWN) + , group(0) + , read_only(false) + , slave_configured(false) + , binlog_relay(false) + , n_slaves_configured(0) + , n_slaves_running(0) + , slave_heartbeats(0) + , heartbeat_period(0) + , latest_event(0) + , gtid_domain_id(-1) +{} + +int64_t MariaDBServer::relay_log_events() +{ + if (slave_status.gtid_io_pos.server_id != SERVER_ID_UNKNOWN && + gtid_current_pos.server_id != SERVER_ID_UNKNOWN && + slave_status.gtid_io_pos.domain == gtid_current_pos.domain && + slave_status.gtid_io_pos.sequence >= gtid_current_pos.sequence) + { + return slave_status.gtid_io_pos.sequence - gtid_current_pos.sequence; + } + return -1; +} + diff --git a/server/modules/monitor/mariadbmon/mariadbserver.hh b/server/modules/monitor/mariadbmon/mariadbserver.hh new file mode 100644 index 000000000..ebadde825 --- /dev/null +++ b/server/modules/monitor/mariadbmon/mariadbserver.hh @@ -0,0 +1,140 @@ +#pragma once + +/* + * Copyright (c) 2016 MariaDB Corporation Ab + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file and at www.mariadb.com/bsl11. + * + * Change Date: 2020-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2 or later of the General + * Public License. + */ + +#include + +#include + +#include + +using std::string; +enum mysql_server_version +{ + MYSQL_SERVER_VERSION_100, + MYSQL_SERVER_VERSION_55, + MYSQL_SERVER_VERSION_51 +}; + +class Gtid +{ +public: + uint32_t domain; + int64_t server_id; // Is actually 32bit unsigned. 0 is only used by server versions <= 10.1 + uint64_t sequence; + Gtid(); + + /** + * Parse a Gtid-triplet from a string. In case of a multi-triplet value, only the triplet with + * the given domain is returned. + * + * @param str Gtid string + * @param search_domain The Gtid domain whose triplet should be returned. Negative domain stands for + * autoselect, which is only allowed when the string contains one triplet. + */ + Gtid(const char* str, int64_t search_domain = -1); + + bool operator == (const Gtid& rhs) const; + + string to_string() const; + + /** + * Generate a MASTER_GTID_WAIT()-query to this gtid. + * + * @param timeout Maximum wait time in seconds + * @return The query + */ + string generate_master_gtid_wait_cmd(double timeout) const; + +private: + void parse_triplet(const char* str); +}; + +// Contains data returned by one row of SHOW ALL SLAVES STATUS +class SlaveStatusInfo +{ +public: + int64_t master_server_id; /**< The master's server_id value. Valid ids are 32bit unsigned. -1 is + * unread/error. */ + string master_host; /**< Master server host name. */ + int master_port; /**< Master server port. */ + bool slave_io_running; /**< Whether the slave I/O thread is running and connected. */ + bool slave_sql_running; /**< Whether or not the SQL thread is running. */ + string master_log_file; /**< Name of the master binary log file that the I/O thread is currently + * reading from. */ + uint64_t read_master_log_pos; /**< Position up to which the I/O thread has read in the current master + * binary log file. */ + Gtid gtid_io_pos; /**< Gtid I/O position of the slave thread. Only shows the triplet with + * the current master domain. */ + string last_error; /**< Last IO or SQL error encountered. */ + + SlaveStatusInfo(); +}; + +// This class groups some miscellaneous replication related settings together. +class ReplicationSettings +{ +public: + bool gtid_strict_mode; /**< Enable additional checks for replication */ + bool log_bin; /**< Is binary logging enabled */ + bool log_slave_updates; /**< Does the slave log replicated events to binlog */ + ReplicationSettings() + : gtid_strict_mode(false) + , log_bin(false) + , log_slave_updates(false) + {} +}; + +/** + * Monitor specific information about a server. Eventually, this will be the primary data structure handled + * by the monitor. These are initialized in @c init_server_info. + */ +class MariaDBServer +{ +public: + MXS_MONITORED_SERVER* server_base; /**< Monitored server base class/struct. MariaDBServer does not + * own the struct, it is not freed (or connection closed) when + * a MariaDBServer is destroyed. Can be const on gcc 4.8 */ + mysql_server_version version; /**< Server version, 10.X, 5.5 or 5.1 */ + int64_t server_id; /**< Value of @@server_id. Valid values are 32bit unsigned. */ + int group; /**< Multi-master group where this server belongs, + * 0 for servers not in groups */ + bool read_only; /**< Value of @@read_only */ + bool slave_configured; /**< Whether SHOW SLAVE STATUS returned rows */ + bool binlog_relay; /** Server is a Binlog Relay */ + int n_slaves_configured; /**< Number of configured slave connections*/ + int n_slaves_running; /**< Number of running slave connections */ + int slave_heartbeats; /**< Number of received heartbeats */ + double heartbeat_period; /**< The time interval between heartbeats */ + time_t latest_event; /**< Time when latest event was received from the master */ + int64_t gtid_domain_id; /**< The value of gtid_domain_id, the domain which is used for + * new non-replicated events. */ + Gtid gtid_current_pos; /**< Gtid of latest event. Only shows the triplet + * with the current master domain. */ + Gtid gtid_binlog_pos; /**< Gtid of latest event written to binlog. Only shows + * the triplet with the current master domain. */ + SlaveStatusInfo slave_status; /**< Data returned from SHOW SLAVE STATUS */ + ReplicationSettings rpl_settings; /**< Miscellaneous replication related settings */ + + MariaDBServer(MXS_MONITORED_SERVER* monitored_server); + + /** + * Calculate how many events are left in the relay log. If gtid_current_pos is ahead of Gtid_IO_Pos, + * or a server_id is unknown, an error value is returned. + * + * @return Number of events in relay log according to latest queried info. A negative value signifies + * an error in the gtid-values. + */ + int64_t relay_log_events(); +}; \ No newline at end of file diff --git a/server/modules/monitor/mariadbmon/utilities.cc b/server/modules/monitor/mariadbmon/utilities.cc index 238ae07e1..bc57ec336 100644 --- a/server/modules/monitor/mariadbmon/utilities.cc +++ b/server/modules/monitor/mariadbmon/utilities.cc @@ -25,97 +25,6 @@ /** Server id default value */ const int64_t SERVER_ID_UNKNOWN = -1; -Gtid::Gtid() - : domain(0) - , server_id(SERVER_ID_UNKNOWN) - , sequence(0) -{} - -Gtid::Gtid(const char* str, int64_t search_domain) - : domain(0) - , server_id(SERVER_ID_UNKNOWN) - , sequence(0) -{ - // Autoselect only allowed with one triplet - ss_dassert(search_domain >= 0 || strchr(str, ',') == NULL); - parse_triplet(str); - if (search_domain >= 0 && domain != search_domain) - { - // Search for the correct triplet. - bool found = false; - for (const char* next_triplet = strchr(str, ','); - next_triplet != NULL && !found; - next_triplet = strchr(next_triplet, ',')) - { - parse_triplet(++next_triplet); - if (domain == search_domain) - { - found = true; - } - } - ss_dassert(found); - } -} - -bool Gtid::operator == (const Gtid& rhs) const -{ - return domain == rhs.domain && - server_id != SERVER_ID_UNKNOWN && server_id == rhs.server_id && - sequence == rhs.sequence; -} - -string Gtid::to_string() const -{ - std::stringstream ss; - if (server_id != SERVER_ID_UNKNOWN) - { - ss << domain << "-" << server_id << "-" << sequence; - } - return ss.str(); -} - -void Gtid::parse_triplet(const char* str) -{ - ss_debug(int rv = ) sscanf(str, "%" PRIu32 "-%" PRId64 "-%" PRIu64, &domain, &server_id, &sequence); - ss_dassert(rv == 3); -} - -SlaveStatusInfo::SlaveStatusInfo() - : master_server_id(SERVER_ID_UNKNOWN) - , master_port(0) - , slave_io_running(false) - , slave_sql_running(false) - , read_master_log_pos(0) -{} - -MariaDBServer::MariaDBServer(MXS_MONITORED_SERVER* monitored_server) - : server_base(monitored_server) - , version(MYSQL_SERVER_VERSION_51) - , server_id(SERVER_ID_UNKNOWN) - , group(0) - , read_only(false) - , slave_configured(false) - , binlog_relay(false) - , n_slaves_configured(0) - , n_slaves_running(0) - , slave_heartbeats(0) - , heartbeat_period(0) - , latest_event(0) - , gtid_domain_id(-1) -{} - -int64_t MariaDBServer::relay_log_events() -{ - if (slave_status.gtid_io_pos.server_id != SERVER_ID_UNKNOWN && - gtid_current_pos.server_id != SERVER_ID_UNKNOWN && - slave_status.gtid_io_pos.domain == gtid_current_pos.domain && - slave_status.gtid_io_pos.sequence >= gtid_current_pos.sequence) - { - return slave_status.gtid_io_pos.sequence - gtid_current_pos.sequence; - } - return -1; -} - int64_t scan_server_id(const char* id_string) { int64_t server_id = SERVER_ID_UNKNOWN; @@ -132,13 +41,6 @@ int64_t scan_server_id(const char* id_string) return server_id; } -string generate_master_gtid_wait_cmd(const Gtid& gtid, double timeout) -{ - std::stringstream query_ss; - query_ss << "SELECT MASTER_GTID_WAIT(\"" << gtid.to_string() << "\", " << timeout << ");"; - return query_ss.str(); -} - bool query_one_row(MXS_MONITORED_SERVER *database, const char* query, unsigned int expected_cols, StringVector* output) { diff --git a/server/modules/monitor/mariadbmon/utilities.hh b/server/modules/monitor/mariadbmon/utilities.hh index 8ee3e65c1..c6ad0b50f 100644 --- a/server/modules/monitor/mariadbmon/utilities.hh +++ b/server/modules/monitor/mariadbmon/utilities.hh @@ -31,120 +31,10 @@ using std::string; -enum mysql_server_version -{ - MYSQL_SERVER_VERSION_100, - MYSQL_SERVER_VERSION_55, - MYSQL_SERVER_VERSION_51 -}; - -extern const int64_t SERVER_ID_UNKNOWN; - typedef std::vector StringVector; typedef std::vector ServerVector; -class Gtid -{ -public: - uint32_t domain; - int64_t server_id; // Is actually 32bit unsigned. 0 is only used by server versions <= 10.1 - uint64_t sequence; - Gtid(); - - /** - * Parse a Gtid-triplet from a string. In case of a multi-triplet value, only the triplet with - * the given domain is returned. - * - * @param str Gtid string - * @param search_domain The Gtid domain whose triplet should be returned. Negative domain stands for - * autoselect, which is only allowed when the string contains one triplet. - */ - Gtid(const char* str, int64_t search_domain = -1); - - bool operator == (const Gtid& rhs) const; - - string to_string() const; -private: - void parse_triplet(const char* str); -}; - -// Contains data returned by one row of SHOW ALL SLAVES STATUS -class SlaveStatusInfo -{ -public: - int64_t master_server_id; /**< The master's server_id value. Valid ids are 32bit unsigned. -1 is - * unread/error. */ - string master_host; /**< Master server host name. */ - int master_port; /**< Master server port. */ - bool slave_io_running; /**< Whether the slave I/O thread is running and connected. */ - bool slave_sql_running; /**< Whether or not the SQL thread is running. */ - string master_log_file; /**< Name of the master binary log file that the I/O thread is currently - * reading from. */ - uint64_t read_master_log_pos; /**< Position up to which the I/O thread has read in the current master - * binary log file. */ - Gtid gtid_io_pos; /**< Gtid I/O position of the slave thread. Only shows the triplet with - * the current master domain. */ - string last_error; /**< Last IO or SQL error encountered. */ - - SlaveStatusInfo(); -}; - -// This class groups some miscellaneous replication related settings together. -class ReplicationSettings -{ -public: - bool gtid_strict_mode; /**< Enable additional checks for replication */ - bool log_bin; /**< Is binary logging enabled */ - bool log_slave_updates; /**< Does the slave log replicated events to binlog */ - ReplicationSettings() - : gtid_strict_mode(false) - , log_bin(false) - , log_slave_updates(false) - {} -}; - -/** - * Monitor specific information about a server. Eventually, this will be the primary data structure handled - * by the monitor. These are initialized in @c init_server_info. - */ -class MariaDBServer -{ -public: - MXS_MONITORED_SERVER* server_base; /**< Monitored server base class/struct. MariaDBServer does not - * own the struct, it is not freed (or connection closed) when - * a MariaDBServer is destroyed. Can be const on gcc 4.8 */ - mysql_server_version version; /**< Server version, 10.X, 5.5 or 5.1 */ - int64_t server_id; /**< Value of @@server_id. Valid values are 32bit unsigned. */ - int group; /**< Multi-master group where this server belongs, - * 0 for servers not in groups */ - bool read_only; /**< Value of @@read_only */ - bool slave_configured; /**< Whether SHOW SLAVE STATUS returned rows */ - bool binlog_relay; /** Server is a Binlog Relay */ - int n_slaves_configured; /**< Number of configured slave connections*/ - int n_slaves_running; /**< Number of running slave connections */ - int slave_heartbeats; /**< Number of received heartbeats */ - double heartbeat_period; /**< The time interval between heartbeats */ - time_t latest_event; /**< Time when latest event was received from the master */ - int64_t gtid_domain_id; /**< The value of gtid_domain_id, the domain which is used for - * new non-replicated events. */ - Gtid gtid_current_pos; /**< Gtid of latest event. Only shows the triplet - * with the current master domain. */ - Gtid gtid_binlog_pos; /**< Gtid of latest event written to binlog. Only shows - * the triplet with the current master domain. */ - SlaveStatusInfo slave_status; /**< Data returned from SHOW SLAVE STATUS */ - ReplicationSettings rpl_settings; /**< Miscellaneous replication related settings */ - - MariaDBServer(MXS_MONITORED_SERVER* monitored_server); - - /** - * Calculate how many events are left in the relay log. If gtid_current_pos is ahead of Gtid_IO_Pos, - * or a server_id is unknown, an error value is returned. - * - * @return Number of events in relay log according to latest queried info. A negative value signifies - * an error in the gtid-values. - */ - int64_t relay_log_events(); -}; +extern const int64_t SERVER_ID_UNKNOWN; /** * Scan a server id from a string. @@ -154,14 +44,6 @@ public: */ int64_t scan_server_id(const char* id_string); -/** - * Generates a MASTER_GTID_WAIT()- query. - * @param gtid What gtid to wait for - * @param timeout Maximum wait time in seconds - * @return The query - */ -string generate_master_gtid_wait_cmd(const Gtid& gtid, double timeout); - /** * Query one row of results, save strings to array. Any additional rows are ignored. *