diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index fcfb5e61b..d93202f73 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -1287,6 +1287,16 @@ The `monitorpw` parameter may be either a plain text password or it may be an encrypted password. See the section on encrypting passwords for use in the maxscale.cnf file. +#### `extra_port` + +An alternative port used to monitor the server. This allows MaxScale to connect +even when `max_connections` has been reached on the backend server. If this +parameter is defined and a connection to the normal port fails, the alternative +port is used. + +For more information, read the +[extra_port documentation](https://mariadb.com/kb/en/library/thread-pool-system-and-status-variables/#extra_port). + #### `persistpoolmax` The `persistpoolmax` parameter defaults to zero but can be set to an integer diff --git a/include/maxscale/config.h b/include/maxscale/config.h index 67e6f5060..bc1b7cbbb 100644 --- a/include/maxscale/config.h +++ b/include/maxscale/config.h @@ -155,6 +155,7 @@ extern const char CN_PASSIVE[]; extern const char CN_PASSWORD[]; extern const char CN_POLL_SLEEP[]; extern const char CN_PORT[]; +extern const char CN_EXTRA_PORT[]; extern const char CN_PROTOCOL[]; extern const char CN_QUERY_CLASSIFIER[]; extern const char CN_QUERY_CLASSIFIER_ARGS[]; diff --git a/include/maxscale/server.h b/include/maxscale/server.h index 074b206d6..c60b4a841 100644 --- a/include/maxscale/server.h +++ b/include/maxscale/server.h @@ -122,6 +122,7 @@ typedef struct server char* name; /**< Server config name */ char address[MAX_SERVER_ADDRESS_LEN]; /**< Server hostname/IP-address */ unsigned short port; /**< Server port */ + unsigned short extra_port; /**< Server extra_port */ char* protocol; /**< Backend protocol module name */ char* authenticator; /**< Authenticator module name */ // Other settings @@ -505,6 +506,7 @@ extern DCB* server_get_persistent(SERVER* server, int id); extern void server_update_address(SERVER* server, const char* address); extern void server_update_port(SERVER* server, unsigned short port); +extern void server_update_extra_port(SERVER* server, unsigned short port); extern uint64_t server_map_status(const char* str); extern void server_set_version_string(SERVER* server, const char* version_string); extern void server_set_version(SERVER* server, const char* version_string, uint64_t version); diff --git a/server/core/config.cc b/server/core/config.cc index a6b69d376..9f2b12d96 100644 --- a/server/core/config.cc +++ b/server/core/config.cc @@ -136,6 +136,7 @@ const char CN_PASSIVE[] = "passive"; const char CN_PASSWORD[] = "password"; const char CN_POLL_SLEEP[] = "poll_sleep"; const char CN_PORT[] = "port"; +const char CN_EXTRA_PORT[] = "extra_port"; const char CN_PROTOCOL[] = "protocol"; const char CN_QUERY_CLASSIFIER[] = "query_classifier"; const char CN_QUERY_CLASSIFIER_ARGS[] = "query_classifier_args"; @@ -402,6 +403,7 @@ const MXS_MODULE_PARAM config_server_params[] = {CN_PROTOCOL, MXS_MODULE_PARAM_STRING, NULL, MXS_MODULE_OPT_REQUIRED}, {CN_PORT, MXS_MODULE_PARAM_COUNT, "3306"}, + {CN_EXTRA_PORT, MXS_MODULE_PARAM_COUNT, "0"}, {CN_AUTHENTICATOR, MXS_MODULE_PARAM_STRING}, {CN_MONITORUSER, MXS_MODULE_PARAM_STRING}, {CN_MONITORPW, MXS_MODULE_PARAM_STRING}, diff --git a/server/core/config_runtime.cc b/server/core/config_runtime.cc index 33844b3e2..02c580dee 100644 --- a/server/core/config_runtime.cc +++ b/server/core/config_runtime.cc @@ -488,6 +488,10 @@ bool runtime_alter_server(SERVER* server, const char* key, const char* value) server_update_port(server, ival); } } + else if (strcmp(key, CN_EXTRA_PORT) == 0) + { + server_update_extra_port(server, atoi(value)); + } else if (strcmp(key, CN_MONITORUSER) == 0) { server_update_credentials(server, value, server->monpw); diff --git a/server/core/mysql_utils.cc b/server/core/mysql_utils.cc index cd0ff41d7..d009fb946 100644 --- a/server/core/mysql_utils.cc +++ b/server/core/mysql_utils.cc @@ -30,6 +30,7 @@ #include #include #include +#include namespace { @@ -191,6 +192,13 @@ MYSQL* mxs_mysql_real_connect(MYSQL* con, SERVER* server, const char* user, cons } MYSQL* mysql = mysql_real_connect(con, server->address, user, passwd, NULL, server->port, NULL, 0); + auto extra_port = mxb::atomic::load(&server->extra_port, mxb::atomic::RELAXED); + + if (!mysql && extra_port) + { + mysql = mysql_real_connect(con, server->address, user, passwd, NULL, extra_port, NULL, 0); + MXS_WARNING("Could not connect with normal port to server '%s', using extra_port", server->name); + } if (mysql) { diff --git a/server/core/server.cc b/server/core/server.cc index 9d466f8ca..8ddede3ce 100644 --- a/server/core/server.cc +++ b/server/core/server.cc @@ -154,6 +154,7 @@ SERVER* server_alloc(const char* name, MXS_CONFIG_PARAMETER* params) server->name = my_name; server->port = config_get_integer(params, CN_PORT); + server->extra_port = config_get_integer(params, CN_EXTRA_PORT); server->protocol = my_protocol; server->authenticator = my_authenticator; server->monuser[0] = '\0'; @@ -1034,6 +1035,18 @@ void server_update_port(SERVER* server, unsigned short port) } } +/* + * Update the extra_port value of a specific server + * + * @param server The server to update + * @param port The new extra_port value + * + */ +void server_update_extra_port(SERVER* server, unsigned short port) +{ + mxb::atomic::store(&server->extra_port, port, mxb::atomic::RELAXED); +} + static struct { const char* str;