From d5d41349aee235e12253df52c3ab9ee900719e0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 20 Nov 2017 11:16:52 +0200 Subject: [PATCH] MXS-1509: Add `ignore_external_masters` parameter The new parameter allows ignoring of master servers that are external to the monitor configuration. This allows sub-trees of the actual replication tree to be used as fully fledged replication trees. --- Documentation/Monitors/MySQL-Monitor.md | 17 +++++++++++++++++ include/maxscale/server.h | 4 ++++ server/modules/monitor/mysqlmon.h | 1 + server/modules/monitor/mysqlmon/mysql_mon.c | 15 +++++++++++++++ 4 files changed, 37 insertions(+) diff --git a/Documentation/Monitors/MySQL-Monitor.md b/Documentation/Monitors/MySQL-Monitor.md index e49459e59..6afe4dca6 100644 --- a/Documentation/Monitors/MySQL-Monitor.md +++ b/Documentation/Monitors/MySQL-Monitor.md @@ -120,6 +120,23 @@ This functionality is similar to the [Multi-Master Monitor](MM-Monitor.md) functionality. The only difference is that the MySQL monitor will also detect traditional Master-Slave topologies. +### `ignore_external_masters` + +Ignore any servers that are not monitored by this monitor but are a part of the +replication topology. This option was added in MaxScale 2.1.12 and is disabled +by default. + +MaxScale detects if a master server replicates from an external server. When +this is detected, the server is assigned the `Slave` and `Slave of External +Server` labels and will be treated as a slave server. Most of the time this +topology is used when MaxScale is used for read scale-out without master +servers, a Galera cluster with read replicas being a prime example of this +setup. Sometimes this is not the desired behavior and the external master server +should be ignored. Most of the time this is due to multi-source replication. + +When this option is enabled, all servers that have the `Master, Slave, Slave of +External Server, Running` labels will instead get the `Master, Running` labels. + ### `detect_standalone_master` Detect standalone master servers. This feature takes a boolean parameter and is diff --git a/include/maxscale/server.h b/include/maxscale/server.h index acbce95be..2fb6e4e77 100644 --- a/include/maxscale/server.h +++ b/include/maxscale/server.h @@ -192,6 +192,10 @@ enum (((server)->status & (SERVER_RUNNING|SERVER_MASTER|SERVER_SLAVE|SERVER_MAINT)) == \ (SERVER_RUNNING|SERVER_MASTER|SERVER_SLAVE)) +#define SERVER_IS_SLAVE_OF_EXTERNAL_MASTER(s) (((s)->status & \ + (SERVER_RUNNING|SERVER_SLAVE_OF_EXTERNAL_MASTER)) == \ + (SERVER_RUNNING|SERVER_SLAVE_OF_EXTERNAL_MASTER)) + /** * @brief Allocate a new server * diff --git a/server/modules/monitor/mysqlmon.h b/server/modules/monitor/mysqlmon.h index ae000150d..1ec15e505 100644 --- a/server/modules/monitor/mysqlmon.h +++ b/server/modules/monitor/mysqlmon.h @@ -66,6 +66,7 @@ typedef struct bool detectStaleMaster; /**< Monitor flag for MySQL replication Stale Master detection */ bool detectStaleSlave; /**< Monitor flag for MySQL replication Stale Master detection */ bool multimaster; /**< Detect and handle multi-master topologies */ + bool ignore_external_masters; /**< Ignore masters outside of the monitor configuration */ int disableMasterFailback; /**< Monitor flag for Galera Cluster Master failback */ int availableWhenDonor; /**< Monitor flag for Galera Cluster Donor availability */ int disableMasterRoleSetting; /**< Monitor flag to disable setting master role */ diff --git a/server/modules/monitor/mysqlmon/mysql_mon.c b/server/modules/monitor/mysqlmon/mysql_mon.c index 5abab0601..14226c14b 100644 --- a/server/modules/monitor/mysqlmon/mysql_mon.c +++ b/server/modules/monitor/mysqlmon/mysql_mon.c @@ -129,6 +129,7 @@ MXS_MODULE* MXS_CREATE_MODULE() {"detect_standalone_master", MXS_MODULE_PARAM_BOOL, "false"}, {"failcount", MXS_MODULE_PARAM_COUNT, "5"}, {"allow_cluster_recovery", MXS_MODULE_PARAM_BOOL, "true"}, + {"ignore_external_masters", MXS_MODULE_PARAM_BOOL, "false"}, { "script", MXS_MODULE_PARAM_PATH, @@ -280,6 +281,7 @@ startMonitor(MXS_MONITOR *monitor, const MXS_CONFIG_PARAMETER* params) handle->detectStaleSlave = config_get_bool(params, "detect_stale_slave"); handle->replicationHeartbeat = config_get_bool(params, "detect_replication_lag"); handle->multimaster = config_get_bool(params, "multimaster"); + handle->ignore_external_masters = config_get_bool(params, "ignore_external_masters"); handle->detect_standalone_master = config_get_bool(params, "detect_standalone_master"); handle->failcount = config_get_integer(params, "failcount"); handle->allow_cluster_recovery = config_get_bool(params, "allow_cluster_recovery"); @@ -1338,6 +1340,19 @@ monitorMain(void *arg) } } + /** + * 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 (root_master && SERVER_IS_SLAVE_OF_EXTERNAL_MASTER(root_master->server) && + SERVER_IS_MASTER(root_master->server) && handle->ignore_external_masters) + { + monitor_clear_pending_status(root_master, + SERVER_SLAVE | SERVER_SLAVE_OF_EXTERNAL_MASTER); + server_clear_status_nolock(root_master->server, SERVER_SLAVE | SERVER_SLAVE_OF_EXTERNAL_MASTER); + } + /** * After updating the status of all servers, check if monitor events * need to be launched.