From 65886dc38697a6d53d8f8d1feb039c81d37ee8d6 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 7 Nov 2016 11:17:01 +0200 Subject: [PATCH] Check whether server references are active Before a query is routed to a backend, the status of the server reference is checked. This allows the servers that are removed from a service to be ejected from the list of active servers for active sessions. --- .../readwritesplit/rwsplit_route_stmt.c | 35 ++++++++++++------- .../readwritesplit/rwsplit_select_backends.c | 7 ++-- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/server/modules/routing/readwritesplit/rwsplit_route_stmt.c b/server/modules/routing/readwritesplit/rwsplit_route_stmt.c index 4ab38b8ed..298358b4f 100644 --- a/server/modules/routing/readwritesplit/rwsplit_route_stmt.c +++ b/server/modules/routing/readwritesplit/rwsplit_route_stmt.c @@ -543,6 +543,7 @@ bool rwsplit_get_dcb(DCB **p_dcb, ROUTER_CLIENT_SES *rses, backend_type_t btype, * server, or master. */ if (BREF_IS_IN_USE((&backend_ref[i])) && + SERVER_REF_IS_ACTIVE(b) && (strncasecmp(name, b->server->unique_name, PATH_MAX) == 0) && (SERVER_IS_SLAVE(&server) || SERVER_IS_RELAY_SERVER(&server) || SERVER_IS_MASTER(&server))) @@ -577,7 +578,7 @@ bool rwsplit_get_dcb(DCB **p_dcb, ROUTER_CLIENT_SES *rses, backend_type_t btype, * Unused backend or backend which is not master nor * slave can't be used */ - if (!BREF_IS_IN_USE(&backend_ref[i]) || + if (!BREF_IS_IN_USE(&backend_ref[i]) || !SERVER_REF_IS_ACTIVE(b) || (!SERVER_IS_MASTER(&server) && !SERVER_IS_SLAVE(&server))) { continue; @@ -665,27 +666,37 @@ bool rwsplit_get_dcb(DCB **p_dcb, ROUTER_CLIENT_SES *rses, backend_type_t btype, */ if (btype == BE_MASTER) { - if (master_bref) + if (master_bref && SERVER_REF_IS_ACTIVE(master_bref->ref)) { /** It is possible for the server status to change at any point in time * so copying it locally will make possible error messages * easier to understand */ SERVER server; server.status = master_bref->ref->server->status; - if (BREF_IS_IN_USE(master_bref) && SERVER_IS_MASTER(&server)) + + if (BREF_IS_IN_USE(master_bref)) { - *p_dcb = master_bref->bref_dcb; - succp = true; - /** if bref is in use DCB should not be closed */ - ss_dassert(master_bref->bref_dcb->state != DCB_STATE_ZOMBIE); + if (SERVER_IS_MASTER(&server)) + { + *p_dcb = master_bref->bref_dcb; + succp = true; + /** if bref is in use DCB should not be closed */ + ss_dassert(master_bref->bref_dcb->state != DCB_STATE_ZOMBIE); + } + else + { + MXS_ERROR("Server '%s' should be master but " + "is %s instead and can't be chosen as the master.", + master_bref->ref->server->unique_name, + STRSRVSTATUS(&server)); + succp = false; + } } else { - MXS_ERROR("Server at %s:%d should be master but " - "is %s instead and can't be chosen to master.", - master_bref->ref->server->name, - master_bref->ref->server->port, - STRSRVSTATUS(&server)); + MXS_ERROR("Server '%s' is not in use and can't be " + "chosen as the master.", + master_bref->ref->server->unique_name); succp = false; } } diff --git a/server/modules/routing/readwritesplit/rwsplit_select_backends.c b/server/modules/routing/readwritesplit/rwsplit_select_backends.c index fba1d7271..35875be65 100644 --- a/server/modules/routing/readwritesplit/rwsplit_select_backends.c +++ b/server/modules/routing/readwritesplit/rwsplit_select_backends.c @@ -106,7 +106,8 @@ bool select_connect_backend_servers(backend_ref_t **p_master_ref, SERVER_REF *master_host = get_root_master(backend_ref, router_nservers); if (router->rwsplit_config.rw_master_failure_mode == RW_FAIL_INSTANTLY && - (master_host == NULL || SERVER_IS_DOWN(master_host->server))) + (master_host == NULL || !SERVER_REF_IS_ACTIVE(master_host) || + SERVER_IS_DOWN(master_host->server))) { MXS_ERROR("Couldn't find suitable Master from %d candidates.", router_nservers); return false; @@ -147,7 +148,9 @@ bool select_connect_backend_servers(backend_ref_t **p_master_ref, { SERVER *serv = backend_ref[i].ref->server; - if (!BREF_HAS_FAILED(&backend_ref[i]) && SERVER_IS_RUNNING(serv)) + if (!BREF_HAS_FAILED(&backend_ref[i]) && + SERVER_REF_IS_ACTIVE(backend_ref[i].ref) && + SERVER_IS_RUNNING(serv)) { /* check also for relay servers and don't take the master_host */ if (slaves_found < max_nslaves &&