From a163e31b9a352114702d2b98dd0f8b50b1238945 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 3 Nov 2016 12:00:33 +0200 Subject: [PATCH] Remove BACKEND structure from readwritesplit The BACKEND structure is no longer created for the instance. This allows sessions to dynamically create new servers. --- include/maxscale/service.h | 1 + server/core/service.c | 1 + .../routing/readwritesplit/readwritesplit.c | 122 +++++------------- .../routing/readwritesplit/readwritesplit.h | 25 +--- .../routing/readwritesplit/rwsplit_mysql.c | 6 +- .../readwritesplit/rwsplit_route_stmt.c | 80 ++++++------ .../readwritesplit/rwsplit_select_backends.c | 113 ++++++++-------- .../readwritesplit/rwsplit_session_cmd.c | 12 +- 8 files changed, 135 insertions(+), 225 deletions(-) diff --git a/include/maxscale/service.h b/include/maxscale/service.h index 74f9c9129..b6d7940d5 100644 --- a/include/maxscale/service.h +++ b/include/maxscale/service.h @@ -100,6 +100,7 @@ typedef struct server_ref_t struct server_ref_t *next; /**< Next server reference */ SERVER* server; /**< The actual server */ int weight; /**< Weight of this server */ + int connections; /**< Number of connections created through this reference */ } SERVER_REF; #define SERVICE_MAX_RETRY_INTERVAL 3600 /*< The maximum interval between service start retries */ diff --git a/server/core/service.c b/server/core/service.c index 6613f0779..f8f2a77a7 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -751,6 +751,7 @@ static SERVER_REF* server_ref_alloc(SERVER *server) sref->next = NULL; sref->server = server; sref->weight = SERVICE_BASE_SERVER_WEIGHT; + sref->connections = 0; } return sref; diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index add637776..357ab9610 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -183,12 +183,7 @@ ROUTER_OBJECT *GetModuleObject() static ROUTER *createInstance(SERVICE *service, char **options) { ROUTER_INSTANCE *router; - SERVER *server; - SERVER_REF *sref; - int nservers; - int i; CONFIG_PARAMETER *param; - char *weightby; if ((router = MXS_CALLOC(1, sizeof(ROUTER_INSTANCE))) == NULL) { @@ -197,51 +192,6 @@ static ROUTER *createInstance(SERVICE *service, char **options) router->service = service; spinlock_init(&router->lock); - /** Calculate number of servers */ - sref = service->dbref; - nservers = 0; - - while (sref != NULL) - { - nservers++; - sref = sref->next; - } - router->servers = (BACKEND **)MXS_CALLOC(nservers + 1, sizeof(BACKEND *)); - - if (router->servers == NULL) - { - free_rwsplit_instance(router); - return NULL; - } - /** - * Create an array of the backend servers in the router structure to - * maintain a count of the number of connections to each - * backend server. - */ - - sref = service->dbref; - nservers = 0; - - while (sref != NULL) - { - if ((router->servers[nservers] = MXS_MALLOC(sizeof(BACKEND))) == NULL) - { - free_rwsplit_instance(router); - return NULL; - } - router->servers[nservers]->backend_server = sref->server; - router->servers[nservers]->backend_conn_count = 0; - router->servers[nservers]->be_valid = false; - router->servers[nservers]->weight = sref->weight; -#if defined(SS_DEBUG) - router->servers[nservers]->be_chk_top = CHK_NUM_BACKEND; - router->servers[nservers]->be_chk_tail = CHK_NUM_BACKEND; -#endif - nservers += 1; - sref = sref->next; - } - router->servers[nservers] = NULL; - /* * Until we know otherwise assume we have some available slaves. */ @@ -268,6 +218,13 @@ static ROUTER *createInstance(SERVICE *service, char **options) router->rwsplit_config.rw_max_sescmd_history_size = 0; } + int nservers = 0; + + for (SERVER_REF *ref = service->dbref; ref; ref = ref->next) + { + nservers++; + } + /** * Set default value for max_slave_connections as 100%. This way * LEAST_CURRENT_OPERATIONS allows us to balance evenly across all the @@ -341,8 +298,7 @@ static ROUTER *createInstance(SERVICE *service, char **options) */ static void *newSession(ROUTER *router_inst, SESSION *session) { - backend_ref_t - *backend_ref; /*< array of backend references (DCB,BACKEND,cursor) */ + backend_ref_t *backend_ref; /*< array of backend references (DCB,BACKEND,cursor) */ backend_ref_t *master_ref = NULL; /*< pointer to selected master */ ROUTER_CLIENT_SES *client_rses = NULL; ROUTER_INSTANCE *router = (ROUTER_INSTANCE *)router_inst; @@ -417,7 +373,8 @@ static void *newSession(ROUTER *router_inst, SESSION *session) * Initialize backend references with BACKEND ptr. * Initialize session command cursors for each backend reference. */ - for (i = 0; i < router_nservers; i++) + i = 0; + for (SERVER_REF *sref = router->service->dbref; sref; sref = sref->next) { #if defined(SS_DEBUG) backend_ref[i].bref_chk_top = CHK_NUM_BACKEND_REF; @@ -426,13 +383,14 @@ static void *newSession(ROUTER *router_inst, SESSION *session) backend_ref[i].bref_sescmd_cur.scmd_cur_chk_tail = CHK_NUM_SESCMD_CUR; #endif backend_ref[i].bref_state = 0; - backend_ref[i].bref_backend = router->servers[i]; + backend_ref[i].ref = sref; /** store pointers to sescmd list to both cursors */ backend_ref[i].bref_sescmd_cur.scmd_cur_rses = client_rses; backend_ref[i].bref_sescmd_cur.scmd_cur_active = false; backend_ref[i].bref_sescmd_cur.scmd_cur_ptr_property = &client_rses->rses_properties[RSES_PROP_TYPE_SESCMD]; backend_ref[i].bref_sescmd_cur.scmd_cur_cmd = NULL; + i++; } max_nslaves = rses_get_max_slavecount(client_rses, router_nservers); max_slave_rlag = rses_get_max_replication_lag(client_rses); @@ -586,7 +544,7 @@ static void closeSession(ROUTER *instance, void *router_session) */ dcb_close(dcb); /** decrease server current connection counters */ - atomic_add(&bref->bref_backend->backend_conn_count, -1); + atomic_add(&bref->ref->connections, -1); } else { @@ -729,7 +687,6 @@ static void diagnostics(ROUTER *instance, DCB *dcb) ROUTER_CLIENT_SES *router_cli_ses; ROUTER_INSTANCE *router = (ROUTER_INSTANCE *)instance; int i = 0; - BACKEND *backend; char *weightby; spinlock_acquire(&router->lock); @@ -770,13 +727,12 @@ static void diagnostics(ROUTER *instance, DCB *dcb) dcb_printf(dcb, "\t\tServer Target %% Connections " "Operations\n"); dcb_printf(dcb, "\t\t Global Router\n"); - for (i = 0; router->servers[i]; i++) + for (SERVER_REF *ref = router->service->dbref; ref; ref = ref->next) { - backend = router->servers[i]; dcb_printf(dcb, "\t\t%-20s %3.1f%% %-6d %-6d %d\n", - backend->backend_server->unique_name, (float)backend->weight / 10, - backend->backend_server->stats.n_current, backend->backend_conn_count, - backend->backend_server->stats.n_current_ops); + ref->server->unique_name, (float)ref->weight / 10, + ref->server->stats.n_current, ref->connections, + ref->server->stats.n_current_ops); } } } @@ -923,17 +879,15 @@ static void clientReply(ROUTER *instance, void *router_session, GWBUF *writebuf, { bool succp; - MXS_INFO("Backend %s:%d processed reply and starts to execute " - "active cursor.", bref->bref_backend->backend_server->name, - bref->bref_backend->backend_server->port); + MXS_INFO("Backend %s:%d processed reply and starts to execute active cursor.", + bref->ref->server->name, bref->ref->server->port); succp = execute_sescmd_in_backend(bref); if (!succp) { MXS_INFO("Backend %s:%d failed to execute session command.", - bref->bref_backend->backend_server->name, - bref->bref_backend->backend_server->port); + bref->ref->server->name, bref->ref->server->port); } } else if (bref->bref_pending_cmd != NULL) /*< non-sescmd is waiting to be routed */ @@ -1092,13 +1046,13 @@ void bref_clear_state(backend_ref_t *bref, bref_state_t state) else { /** Decrease global operation count */ - prev2 = atomic_add(&bref->bref_backend->backend_server->stats.n_current_ops, -1); + prev2 = atomic_add(&bref->ref->server->stats.n_current_ops, -1); ss_dassert(prev2 > 0); if (prev2 <= 0) { MXS_ERROR("[%s] Error: negative current operation count in backend %s:%u", - __FUNCTION__, bref->bref_backend->backend_server->name, - bref->bref_backend->backend_server->port); + __FUNCTION__, bref->ref->server->name, + bref->ref->server->port); } } } @@ -1137,19 +1091,16 @@ void bref_set_state(backend_ref_t *bref, bref_state_t state) if (prev1 < 0) { MXS_ERROR("[%s] Error: negative number of connections waiting for " - "results in backend %s:%u", - __FUNCTION__, bref->bref_backend->backend_server->name, - bref->bref_backend->backend_server->port); + "results in backend %s:%u", __FUNCTION__, + bref->ref->server->name, bref->ref->server->port); } /** Increase global operation count */ - prev2 = - atomic_add(&bref->bref_backend->backend_server->stats.n_current_ops, 1); + prev2 = atomic_add(&bref->ref->server->stats.n_current_ops, 1); ss_dassert(prev2 >= 0); if (prev2 < 0) { MXS_ERROR("[%s] Error: negative current operation count in backend %s:%u", - __FUNCTION__, bref->bref_backend->backend_server->name, - bref->bref_backend->backend_server->port); + __FUNCTION__, bref->ref->server->name, bref->ref->server->port); } } @@ -1316,7 +1267,7 @@ int router_handle_state_switch(DCB *dcb, DCB_REASON reason, void *data) bref = (backend_ref_t *)data; CHK_BACKEND_REF(bref); - srv = bref->bref_backend->backend_server; + srv = bref->ref->server; if (SERVER_IS_RUNNING(srv) && SERVER_IS_IN_CLUSTER(srv)) { @@ -1531,9 +1482,9 @@ static void handleError(ROUTER *instance, void *router_session, * handled so that session could continue. */ if (rses->rses_master_ref && rses->rses_master_ref->bref_dcb == problem_dcb && - !SERVER_IS_MASTER(rses->rses_master_ref->bref_backend->backend_server)) + !SERVER_IS_MASTER(rses->rses_master_ref->ref->server)) { - SERVER *srv = rses->rses_master_ref->bref_backend->backend_server; + SERVER *srv = rses->rses_master_ref->ref->server; backend_ref_t *bref; bref = get_bref_from_dcb(rses, problem_dcb); if (bref != NULL) @@ -1794,9 +1745,8 @@ return_succp: static int router_get_servercount(ROUTER_INSTANCE *inst) { int router_nservers = 0; - BACKEND **b = inst->servers; - /** count servers */ - while (*(b++) != NULL) + + for (SERVER_REF *ref = inst->service->dbref; ref; ref = ref->next) { router_nservers++; } @@ -2074,14 +2024,6 @@ static void free_rwsplit_instance(ROUTER_INSTANCE *router) { if (router) { - if (router->servers) - { - for (int i = 0; router->servers[i]; i++) - { - MXS_FREE(router->servers[i]); - } - } - MXS_FREE(router->servers); MXS_FREE(router); } } diff --git a/server/modules/routing/readwritesplit/readwritesplit.h b/server/modules/routing/readwritesplit/readwritesplit.h index 98020b667..5a8d9dd36 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.h +++ b/server/modules/routing/readwritesplit/readwritesplit.h @@ -199,27 +199,6 @@ typedef struct sescmd_cursor_st #endif } sescmd_cursor_t; -/** - * Internal structure used to define the set of backend servers we are routing - * connections to. This provides the storage for routing module specific data - * that is required for each of the backend servers. - * - * Owned by router_instance, referenced by each routing session. - */ -typedef struct backend_st -{ -#if defined(SS_DEBUG) - skygw_chk_t be_chk_top; -#endif - SERVER* backend_server; /*< The server itself */ - int backend_conn_count; /*< Number of connections to the server */ - bool be_valid; /*< Valid when belongs to the router's configuration */ - int weight; /*< Desired weighting on the load. Expressed in .1% increments */ -#if defined(SS_DEBUG) - skygw_chk_t be_chk_tail; -#endif -} BACKEND; - /** * Reference to BACKEND. * @@ -230,7 +209,7 @@ typedef struct backend_ref_st #if defined(SS_DEBUG) skygw_chk_t bref_chk_top; #endif - BACKEND* bref_backend; + SERVER_REF* ref; DCB* bref_dcb; bref_state_t bref_state; int bref_num_result_wait; @@ -348,8 +327,6 @@ typedef struct router_instance SERVICE* service; /*< Pointer to service */ ROUTER_CLIENT_SES* connections; /*< List of client connections */ SPINLOCK lock; /*< Lock for the instance data */ - BACKEND** servers; /*< Backend servers */ - BACKEND* master; /*< NULL or pointer */ rwsplit_config_t rwsplit_config; /*< expanded config info from SERVICE */ int rwsplit_version; /*< version number for router's config */ ROUTER_STATS stats; /*< Statistics for this router */ diff --git a/server/modules/routing/readwritesplit/rwsplit_mysql.c b/server/modules/routing/readwritesplit/rwsplit_mysql.c index dbad88573..6dcdd50d5 100644 --- a/server/modules/routing/readwritesplit/rwsplit_mysql.c +++ b/server/modules/routing/readwritesplit/rwsplit_mysql.c @@ -404,7 +404,7 @@ void print_error_packet(ROUTER_CLIENT_SES *rses, GWBUF *buf, DCB *dcb) { if (bref[i].bref_dcb == dcb) { - srv = bref[i].bref_backend->backend_server; + srv = bref[i].ref->server; } } ss_dassert(srv != NULL); @@ -453,8 +453,8 @@ void check_session_command_reply(GWBUF *writebuf, sescmd_cursor_t *scur, backend ss_dassert(len + 4 == GWBUF_LENGTH(scur->scmd_cur_cmd->my_sescmd_buf)); MXS_ERROR("Failed to execute session command in %s:%d. Error was: %s %s", - bref->bref_backend->backend_server->name, - bref->bref_backend->backend_server->port, err, replystr); + bref->ref->server->name, + bref->ref->server->port, err, replystr); MXS_FREE(err); MXS_FREE(replystr); } diff --git a/server/modules/routing/readwritesplit/rwsplit_route_stmt.c b/server/modules/routing/readwritesplit/rwsplit_route_stmt.c index cdaddc5ca..ae6e42e1f 100644 --- a/server/modules/routing/readwritesplit/rwsplit_route_stmt.c +++ b/server/modules/routing/readwritesplit/rwsplit_route_stmt.c @@ -253,10 +253,10 @@ bool route_session_write(ROUTER_CLIENT_SES *router_cli_ses, BREF_IS_IN_USE((&backend_ref[i]))) { MXS_INFO("Route query to %s \t%s:%d%s", - (SERVER_IS_MASTER(backend_ref[i].bref_backend->backend_server) + (SERVER_IS_MASTER(backend_ref[i].ref->server) ? "master" : "slave"), - backend_ref[i].bref_backend->backend_server->name, - backend_ref[i].bref_backend->backend_server->port, + backend_ref[i].ref->server->name, + backend_ref[i].ref->server->port, (i + 1 == router_cli_ses->rses_nbackends ? " <" : " ")); } @@ -368,10 +368,10 @@ bool route_session_write(ROUTER_CLIENT_SES *router_cli_ses, if (MXS_LOG_PRIORITY_IS_ENABLED(LOG_INFO)) { MXS_INFO("Route query to %s \t%s:%d%s", - (SERVER_IS_MASTER(backend_ref[i].bref_backend->backend_server) + (SERVER_IS_MASTER(backend_ref[i].ref->server) ? "master" : "slave"), - backend_ref[i].bref_backend->backend_server->name, - backend_ref[i].bref_backend->backend_server->port, + backend_ref[i].ref->server->name, + backend_ref[i].ref->server->port, (i + 1 == router_cli_ses->rses_nbackends ? " <" : " ")); } @@ -391,8 +391,8 @@ bool route_session_write(ROUTER_CLIENT_SES *router_cli_ses, { nsucc += 1; MXS_INFO("Backend %s:%d already executing sescmd.", - backend_ref[i].bref_backend->backend_server->name, - backend_ref[i].bref_backend->backend_server->port); + backend_ref[i].ref->server->name, + backend_ref[i].ref->server->port); } else { @@ -403,8 +403,8 @@ bool route_session_write(ROUTER_CLIENT_SES *router_cli_ses, else { MXS_ERROR("Failed to execute session command in %s:%d", - backend_ref[i].bref_backend->backend_server->name, - backend_ref[i].bref_backend->backend_server->port); + backend_ref[i].ref->server->name, + backend_ref[i].ref->server->port); } } } @@ -533,9 +533,9 @@ bool rwsplit_get_dcb(DCB **p_dcb, ROUTER_CLIENT_SES *rses, backend_type_t btype, for (i = 0; i < rses->rses_nbackends; i++) { - BACKEND *b = backend_ref[i].bref_backend; + SERVER_REF *b = backend_ref[i].ref; SERVER server; - server.status = backend_ref[i].bref_backend->backend_server->status; + server.status = b->server->status; /** * To become chosen: * backend must be in use, name must match, @@ -543,7 +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])) && - (strncasecmp(name, b->backend_server->unique_name, PATH_MAX) == 0) && + (strncasecmp(name, b->server->unique_name, PATH_MAX) == 0) && (SERVER_IS_SLAVE(&server) || SERVER_IS_RELAY_SERVER(&server) || SERVER_IS_MASTER(&server))) { @@ -569,10 +569,10 @@ bool rwsplit_get_dcb(DCB **p_dcb, ROUTER_CLIENT_SES *rses, backend_type_t btype, for (i = 0; i < rses->rses_nbackends; i++) { - BACKEND *b = (&backend_ref[i])->bref_backend; + SERVER_REF *b = backend_ref[i].ref; SERVER server; SERVER candidate; - server.status = backend_ref[i].bref_backend->backend_server->status; + server.status = b->server->status; /** * Unused backend or backend which is not master nor * slave can't be used @@ -596,7 +596,7 @@ bool rwsplit_get_dcb(DCB **p_dcb, ROUTER_CLIENT_SES *rses, backend_type_t btype, { /** found master */ candidate_bref = &backend_ref[i]; - candidate.status = candidate_bref->bref_backend->backend_server->status; + candidate.status = candidate_bref->ref->server->status; succp = true; } /** @@ -605,12 +605,12 @@ bool rwsplit_get_dcb(DCB **p_dcb, ROUTER_CLIENT_SES *rses, backend_type_t btype, * maximum allowed replication lag. */ else if (max_rlag == MAX_RLAG_UNDEFINED || - (b->backend_server->rlag != MAX_RLAG_NOT_AVAILABLE && - b->backend_server->rlag <= max_rlag)) + (b->server->rlag != MAX_RLAG_NOT_AVAILABLE && + b->server->rlag <= max_rlag)) { /** found slave */ candidate_bref = &backend_ref[i]; - candidate.status = candidate_bref->bref_backend->backend_server->status; + candidate.status = candidate_bref->ref->server->status; succp = true; } } @@ -620,13 +620,13 @@ bool rwsplit_get_dcb(DCB **p_dcb, ROUTER_CLIENT_SES *rses, backend_type_t btype, */ else if (SERVER_IS_MASTER(&candidate) && SERVER_IS_SLAVE(&server) && (max_rlag == MAX_RLAG_UNDEFINED || - (b->backend_server->rlag != MAX_RLAG_NOT_AVAILABLE && - b->backend_server->rlag <= max_rlag)) && + (b->server->rlag != MAX_RLAG_NOT_AVAILABLE && + b->server->rlag <= max_rlag)) && !rses->rses_config.rw_master_reads) { /** found slave */ candidate_bref = &backend_ref[i]; - candidate.status = candidate_bref->bref_backend->backend_server->status; + candidate.status = candidate_bref->ref->server->status; succp = true; } /** @@ -637,21 +637,17 @@ bool rwsplit_get_dcb(DCB **p_dcb, ROUTER_CLIENT_SES *rses, backend_type_t btype, else if (SERVER_IS_SLAVE(&server)) { if (max_rlag == MAX_RLAG_UNDEFINED || - (b->backend_server->rlag != MAX_RLAG_NOT_AVAILABLE && - b->backend_server->rlag <= max_rlag)) + (b->server->rlag != MAX_RLAG_NOT_AVAILABLE && + b->server->rlag <= max_rlag)) { - candidate_bref = - check_candidate_bref(candidate_bref, &backend_ref[i], - rses->rses_config.rw_slave_select_criteria); - candidate.status = - candidate_bref->bref_backend->backend_server->status; + candidate_bref = check_candidate_bref(candidate_bref, &backend_ref[i], + rses->rses_config.rw_slave_select_criteria); + candidate.status = candidate_bref->ref->server->status; } else { - MXS_INFO("Server %s:%d is too much behind the " - "master, %d s. and can't be chosen.", - b->backend_server->name, b->backend_server->port, - b->backend_server->rlag); + MXS_INFO("Server %s:%d is too much behind the master, %d s. and can't be chosen.", + b->server->name, b->server->port, b->server->rlag); } } } /*< for */ @@ -675,7 +671,7 @@ bool rwsplit_get_dcb(DCB **p_dcb, ROUTER_CLIENT_SES *rses, backend_type_t btype, * so copying it locally will make possible error messages * easier to understand */ SERVER server; - server.status = master_bref->bref_backend->backend_server->status; + server.status = master_bref->ref->server->status; if (BREF_IS_IN_USE(master_bref) && SERVER_IS_MASTER(&server)) { *p_dcb = master_bref->bref_dcb; @@ -687,8 +683,8 @@ bool rwsplit_get_dcb(DCB **p_dcb, ROUTER_CLIENT_SES *rses, backend_type_t btype, { MXS_ERROR("Server at %s:%d should be master but " "is %s instead and can't be chosen to master.", - master_bref->bref_backend->backend_server->name, - master_bref->bref_backend->backend_server->port, + master_bref->ref->server->name, + master_bref->ref->server->port, STRSRVSTATUS(&server)); succp = false; } @@ -1191,9 +1187,8 @@ handle_got_target(ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses, ss_dassert(target_dcb != NULL); MXS_INFO("Route query to %s \t%s:%d <", - (SERVER_IS_MASTER(bref->bref_backend->backend_server) ? "master" - : "slave"), bref->bref_backend->backend_server->name, - bref->bref_backend->backend_server->port); + (SERVER_IS_MASTER(bref->ref->server) ? "master" + : "slave"), bref->ref->server->name, bref->ref->server->port); /** * Store current stmt if execution of previous session command * haven't completed yet. @@ -1372,14 +1367,13 @@ static backend_ref_t *get_root_master_bref(ROUTER_CLIENT_SES *rses) if (bref == rses->rses_master_ref) { /** Store master state for better error reporting */ - master.status = bref->bref_backend->backend_server->status; + master.status = bref->ref->server->status; } - if (bref->bref_backend->backend_server->status & SERVER_MASTER) + if (SERVER_IS_MASTER(bref->ref->server)) { if (candidate_bref == NULL || - (bref->bref_backend->backend_server->depth < - candidate_bref->bref_backend->backend_server->depth)) + (bref->ref->server->depth < candidate_bref->ref->server->depth)) { candidate_bref = bref; } diff --git a/server/modules/routing/readwritesplit/rwsplit_select_backends.c b/server/modules/routing/readwritesplit/rwsplit_select_backends.c index 1198dec52..fba1d7271 100644 --- a/server/modules/routing/readwritesplit/rwsplit_select_backends.c +++ b/server/modules/routing/readwritesplit/rwsplit_select_backends.c @@ -38,7 +38,7 @@ static bool connect_server(backend_ref_t *bref, SESSION *session, bool execute_h static void log_server_connections(select_criteria_t select_criteria, backend_ref_t *backend_ref, int router_nservers); -static BACKEND *get_root_master(backend_ref_t *servers, int router_nservers); +static SERVER_REF *get_root_master(backend_ref_t *servers, int router_nservers); static int bref_cmp_global_conn(const void *bref1, const void *bref2); @@ -103,10 +103,10 @@ bool select_connect_backend_servers(backend_ref_t **p_master_ref, } /* get the root Master */ - BACKEND *master_host = get_root_master(backend_ref, router_nservers); + 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->backend_server))) + (master_host == NULL || SERVER_IS_DOWN(master_host->server))) { MXS_ERROR("Couldn't find suitable Master from %d candidates.", router_nservers); return false; @@ -145,7 +145,7 @@ bool select_connect_backend_servers(backend_ref_t **p_master_ref, for (int i = 0; i < router_nservers && (slaves_connected < max_nslaves || !master_connected); i++) { - SERVER *serv = backend_ref[i].bref_backend->backend_server; + SERVER *serv = backend_ref[i].ref->server; if (!BREF_HAS_FAILED(&backend_ref[i]) && SERVER_IS_RUNNING(serv)) { @@ -155,7 +155,7 @@ bool select_connect_backend_servers(backend_ref_t **p_master_ref, (serv->rlag != MAX_RLAG_NOT_AVAILABLE && serv->rlag <= max_slave_rlag)) && (SERVER_IS_SLAVE(serv) || SERVER_IS_RELAY_SERVER(serv)) && - (master_host == NULL || (serv != master_host->backend_server))) + (master_host == NULL || (serv != master_host->server))) { slaves_found += 1; @@ -166,7 +166,7 @@ bool select_connect_backend_servers(backend_ref_t **p_master_ref, } } /* take the master_host for master */ - else if (master_host && (serv == master_host->backend_server)) + else if (master_host && (serv == master_host->server)) { /** p_master_ref must be assigned with this backend_ref pointer * because its original value may have been lost when backend @@ -205,9 +205,9 @@ bool select_connect_backend_servers(backend_ref_t **p_master_ref, if (BREF_IS_IN_USE((&backend_ref[i]))) { MXS_INFO("Selected %s in \t%s:%d", - STRSRVSTATUS(backend_ref[i].bref_backend->backend_server), - backend_ref[i].bref_backend->backend_server->name, - backend_ref[i].bref_backend->backend_server->port); + STRSRVSTATUS(backend_ref[i].ref->server), + backend_ref[i].ref->server->name, + backend_ref[i].ref->server->port); } } /* for */ } @@ -226,12 +226,12 @@ bool select_connect_backend_servers(backend_ref_t **p_master_ref, { if (BREF_IS_IN_USE((&backend_ref[i]))) { - ss_dassert(backend_ref[i].bref_backend->backend_conn_count > 0); + ss_dassert(backend_ref[i].ref->connections > 0); /** disconnect opened connections */ bref_clear_state(&backend_ref[i], BREF_IN_USE); /** Decrease backend's connection counter. */ - atomic_add(&backend_ref[i].bref_backend->backend_conn_count, -1); + atomic_add(&backend_ref[i].ref->connections, -1); dcb_close(backend_ref[i].bref_dcb); } } @@ -243,13 +243,12 @@ bool select_connect_backend_servers(backend_ref_t **p_master_ref, /** Compare number of connections from this router in backend servers */ static int bref_cmp_router_conn(const void *bref1, const void *bref2) { - BACKEND *b1 = ((backend_ref_t *)bref1)->bref_backend; - BACKEND *b2 = ((backend_ref_t *)bref2)->bref_backend; + SERVER_REF *b1 = ((backend_ref_t *)bref1)->ref; + SERVER_REF *b2 = ((backend_ref_t *)bref2)->ref; if (b1->weight == 0 && b2->weight == 0) { - return b1->backend_server->stats.n_current - - b2->backend_server->stats.n_current; + return b1->connections - b2->connections; } else if (b1->weight == 0) { @@ -260,20 +259,20 @@ static int bref_cmp_router_conn(const void *bref1, const void *bref2) return -1; } - return ((1000 + 1000 * b1->backend_conn_count) / b1->weight) - - ((1000 + 1000 * b2->backend_conn_count) / b2->weight); + return ((1000 + 1000 * b1->connections) / b1->weight) - + ((1000 + 1000 * b2->connections) / b2->weight); } /** Compare number of global connections in backend servers */ static int bref_cmp_global_conn(const void *bref1, const void *bref2) { - BACKEND *b1 = ((backend_ref_t *)bref1)->bref_backend; - BACKEND *b2 = ((backend_ref_t *)bref2)->bref_backend; + SERVER_REF *b1 = ((backend_ref_t *)bref1)->ref; + SERVER_REF *b2 = ((backend_ref_t *)bref2)->ref; if (b1->weight == 0 && b2->weight == 0) { - return b1->backend_server->stats.n_current - - b2->backend_server->stats.n_current; + return b1->server->stats.n_current - + b2->server->stats.n_current; } else if (b1->weight == 0) { @@ -284,32 +283,29 @@ static int bref_cmp_global_conn(const void *bref1, const void *bref2) return -1; } - return ((1000 + 1000 * b1->backend_server->stats.n_current) / b1->weight) - - ((1000 + 1000 * b2->backend_server->stats.n_current) / b2->weight); + return ((1000 + 1000 * b1->server->stats.n_current) / b1->weight) - + ((1000 + 1000 * b2->server->stats.n_current) / b2->weight); } /** Compare replication lag between backend servers */ static int bref_cmp_behind_master(const void *bref1, const void *bref2) { - BACKEND *b1 = ((backend_ref_t *)bref1)->bref_backend; - BACKEND *b2 = ((backend_ref_t *)bref2)->bref_backend; + SERVER_REF *b1 = ((backend_ref_t *)bref1)->ref; + SERVER_REF *b2 = ((backend_ref_t *)bref2)->ref; - return ((b1->backend_server->rlag < b2->backend_server->rlag) ? -1 - : ((b1->backend_server->rlag > b2->backend_server->rlag) ? 1 : 0)); + return b1->server->rlag - b2->server->rlag; } /** Compare number of current operations in backend servers */ static int bref_cmp_current_load(const void *bref1, const void *bref2) { - SERVER *s1 = ((backend_ref_t *)bref1)->bref_backend->backend_server; - SERVER *s2 = ((backend_ref_t *)bref2)->bref_backend->backend_server; - BACKEND *b1 = ((backend_ref_t *)bref1)->bref_backend; - BACKEND *b2 = ((backend_ref_t *)bref2)->bref_backend; + SERVER_REF *b1 = ((backend_ref_t *)bref1)->ref; + SERVER_REF *b2 = ((backend_ref_t *)bref2)->ref; if (b1->weight == 0 && b2->weight == 0) { - return b1->backend_server->stats.n_current - - b2->backend_server->stats.n_current; + // TODO: Fix this so that operations are used instead of connections + return b1->server->stats.n_current - b2->server->stats.n_current; } else if (b1->weight == 0) { @@ -320,8 +316,8 @@ static int bref_cmp_current_load(const void *bref1, const void *bref2) return -1; } - return ((1000 * s1->stats.n_current_ops) - b1->weight) - - ((1000 * s2->stats.n_current_ops) - b2->weight); + return ((1000 * b1->server->stats.n_current_ops) - b1->weight) - + ((1000 * b2->server->stats.n_current_ops) - b2->weight); } /** @@ -338,7 +334,7 @@ static int bref_cmp_current_load(const void *bref1, const void *bref2) */ static bool connect_server(backend_ref_t *bref, SESSION *session, bool execute_history) { - SERVER *serv = bref->bref_backend->backend_server; + SERVER *serv = bref->ref->server; bool rval = false; bref->bref_dcb = dcb_connect(serv, session, serv->protocol); @@ -354,16 +350,16 @@ static bool connect_server(backend_ref_t *bref, SESSION *session, bool execute_h &router_handle_state_switch, (void *) bref); bref->bref_state = 0; bref_set_state(bref, BREF_IN_USE); - atomic_add(&bref->bref_backend->backend_conn_count, 1); + atomic_add(&bref->ref->connections, 1); rval = true; } else { MXS_ERROR("Failed to execute session command in %s (%s:%d). See earlier " "errors for more details.", - bref->bref_backend->backend_server->unique_name, - bref->bref_backend->backend_server->name, - bref->bref_backend->backend_server->port); + bref->ref->server->unique_name, + bref->ref->server->name, + bref->ref->server->port); dcb_close(bref->bref_dcb); bref->bref_dcb = NULL; } @@ -398,33 +394,33 @@ static void log_server_connections(select_criteria_t select_criteria, for (int i = 0; i < router_nservers; i++) { - BACKEND *b = backend_ref[i].bref_backend; + SERVER_REF *b = backend_ref[i].ref; switch (select_criteria) { case LEAST_GLOBAL_CONNECTIONS: MXS_INFO("MaxScale connections : %d in \t%s:%d %s", - b->backend_server->stats.n_current, b->backend_server->name, - b->backend_server->port, STRSRVSTATUS(b->backend_server)); + b->server->stats.n_current, b->server->name, + b->server->port, STRSRVSTATUS(b->server)); break; case LEAST_ROUTER_CONNECTIONS: MXS_INFO("RWSplit connections : %d in \t%s:%d %s", - b->backend_conn_count, b->backend_server->name, - b->backend_server->port, STRSRVSTATUS(b->backend_server)); + b->connections, b->server->name, + b->server->port, STRSRVSTATUS(b->server)); break; case LEAST_CURRENT_OPERATIONS: MXS_INFO("current operations : %d in \t%s:%d %s", - b->backend_server->stats.n_current_ops, - b->backend_server->name, b->backend_server->port, - STRSRVSTATUS(b->backend_server)); + b->server->stats.n_current_ops, + b->server->name, b->server->port, + STRSRVSTATUS(b->server)); break; case LEAST_BEHIND_MASTER: MXS_INFO("replication lag : %d in \t%s:%d %s", - b->backend_server->rlag, b->backend_server->name, - b->backend_server->port, STRSRVSTATUS(b->backend_server)); + b->server->rlag, b->server->name, + b->server->port, STRSRVSTATUS(b->server)); default: break; } @@ -445,27 +441,26 @@ static void log_server_connections(select_criteria_t select_criteria, * @return The Master found * */ -static BACKEND *get_root_master(backend_ref_t *servers, int router_nservers) +static SERVER_REF *get_root_master(backend_ref_t *servers, int router_nservers) { int i = 0; - BACKEND *master_host = NULL; + SERVER_REF *master_host = NULL; for (i = 0; i < router_nservers; i++) { - BACKEND *b; - - if (servers[i].bref_backend == NULL) + if (servers[i].ref == NULL) { + /** This should not happen */ + ss_dassert(false); continue; } - b = servers[i].bref_backend; + SERVER_REF *b = servers[i].ref; - if ((b->backend_server->status & (SERVER_MASTER | SERVER_MAINT)) == - SERVER_MASTER) + if (SERVER_IS_MASTER(b->server)) { if (master_host == NULL || - (b->backend_server->depth < master_host->backend_server->depth)) + (b->server->depth < master_host->server->depth)) { master_host = b; } diff --git a/server/modules/routing/readwritesplit/rwsplit_session_cmd.c b/server/modules/routing/readwritesplit/rwsplit_session_cmd.c index b37951543..f06bf96e0 100644 --- a/server/modules/routing/readwritesplit/rwsplit_session_cmd.c +++ b/server/modules/routing/readwritesplit/rwsplit_session_cmd.c @@ -173,7 +173,7 @@ GWBUF *sescmd_cursor_process_replies(GWBUF *replybuf, { MXS_ERROR("Slave server '%s': response differs from master's response. " "Closing connection due to inconsistent session state.", - bref->bref_backend->backend_server->unique_name); + bref->ref->server->unique_name); sescmd_cursor_set_active(scur, false); bref_clear_state(bref, BREF_QUERY_ACTIVE); bref_clear_state(bref, BREF_IN_USE); @@ -205,7 +205,7 @@ GWBUF *sescmd_cursor_process_replies(GWBUF *replybuf, scmd->reply_cmd = *((unsigned char *)replybuf->start + 4); MXS_INFO("Server '%s' responded to a session command, sending the response " - "to the client.", bref->bref_backend->backend_server->unique_name); + "to the client.", bref->ref->server->unique_name); for (int i = 0; i < ses->rses_nbackends; i++) { @@ -226,8 +226,8 @@ GWBUF *sescmd_cursor_process_replies(GWBUF *replybuf, *reconnect = true; MXS_INFO("Disabling slave %s:%d, result differs from " "master's result. Master: %d Slave: %d", - ses->rses_backend_ref[i].bref_backend->backend_server->name, - ses->rses_backend_ref[i].bref_backend->backend_server->port, + ses->rses_backend_ref[i].ref->server->name, + ses->rses_backend_ref[i].ref->server->port, bref->reply_cmd, ses->rses_backend_ref[i].reply_cmd); } } @@ -237,11 +237,11 @@ GWBUF *sescmd_cursor_process_replies(GWBUF *replybuf, else { MXS_INFO("Slave '%s' responded before master to a session command. Result: %d", - bref->bref_backend->backend_server->unique_name, + bref->ref->server->unique_name, (int)bref->reply_cmd); if (bref->reply_cmd == 0xff) { - SERVER *serv = bref->bref_backend->backend_server; + SERVER *serv = bref->ref->server; MXS_ERROR("Slave '%s' (%s:%u) failed to execute session command.", serv->unique_name, serv->name, serv->port); }