From dbf12f61836f79ac0bf9db9ff084c0efdd0e56b0 Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Wed, 25 Jun 2014 18:38:33 +0200 Subject: [PATCH] Added new rules for Master selection Added new rules for Master selection using replication tree --- .../routing/readwritesplit/readwritesplit.c | 86 ++++++++++++++++--- 1 file changed, 74 insertions(+), 12 deletions(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 8086029aa..e2a12fe0d 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -232,6 +232,10 @@ static void bref_set_state(backend_ref_t* bref, bref_state_t state); static int router_handle_state_switch(DCB* dcb, DCB_REASON reason, void* data); +static BACKEND *get_root_master( + backend_ref_t *servers, + int router_nservers); + static SPINLOCK instlock; static ROUTER_INSTANCE* instances; @@ -610,7 +614,8 @@ static void* newSession( } /** Copy backend pointers to router session. */ client_rses->rses_master_ref = master_ref; - ss_dassert(SERVER_IS_MASTER(master_ref->bref_backend->backend_server)); + /* assert with master_host */ + ss_dassert(master_host && ((*p_master_ref)->bref_backend->backend_server == master_host->backend_server) && SERVER_MASTER); client_rses->rses_backend_ref = backend_ref; client_rses->rses_nbackends = router_nservers; /*< # of backend servers */ client_rses->rses_capabilities = RCAP_TYPE_STMT_INPUT; @@ -791,6 +796,7 @@ static bool get_dcb( int smallest_nconn = -1; int i; bool succp = false; + BACKEND *master_host = NULL; CHK_CLIENT_RSES(rses); ss_dassert(p_dcb != NULL && *(p_dcb) == NULL); @@ -801,13 +807,18 @@ static bool get_dcb( } backend_ref = rses->rses_backend_ref; + /* get root master from availbal servers */ + master_host = get_root_master(backend_ref, rses->rses_nbackends); + if (btype == BE_SLAVE) { for (i=0; irses_nbackends; i++) { BACKEND* b = backend_ref[i].bref_backend; + /* check slave bit, also for relay servers (Master & Servers) */ if (BREF_IS_IN_USE((&backend_ref[i])) && - SERVER_IS_SLAVE(b->backend_server) && + (SERVER_IS_SLAVE(b->backend_server) || SERVER_IS_RELAY_SERVER(b->backend_server)) && + (master_host != NULL && b->backend_server != master_host->backend_server) && (smallest_nconn == -1 || b->backend_conn_count < smallest_nconn)) { @@ -825,9 +836,10 @@ static bool get_dcb( { *p_dcb = backend_ref->bref_dcb; succp = true; - + + /* this was changed */ ss_dassert( - SERVER_IS_MASTER(backend_ref->bref_backend->backend_server) && + (master_host && (b->backend_server == master_host->backend_server)) && smallest_nconn == -1); LOGIF(LE, (skygw_log_write_flush( @@ -847,8 +859,9 @@ static bool get_dcb( { BACKEND* b = backend_ref[i].bref_backend; + /* removed SERVER_IS_MASTER and use master_host */ if (BREF_IS_IN_USE((&backend_ref[i])) && - (SERVER_IS_MASTER(b->backend_server))) + (master_host && (b->backend_server == master_host->backend_server))) { *p_dcb = backend_ref[i].bref_dcb; succp = true; @@ -1475,6 +1488,7 @@ static bool select_connect_backend_servers( const int min_nslaves = 0; /*< not configurable at the time */ bool is_synced_master; int (*p)(const void *, const void *); + BACKEND *master_host = NULL; if (p_master_ref == NULL || backend_ref == NULL) { @@ -1482,7 +1496,10 @@ static bool select_connect_backend_servers( succp = false; goto return_succp; } - + + /* get the root Master */ + master_host = get_root_master(backend_ref, router_nservers); + /** Master is already chosen and connected. This is slave failure case */ if (*p_master_ref != NULL && BREF_IS_IN_USE((*p_master_ref))) @@ -1496,7 +1513,8 @@ static bool select_connect_backend_servers( master_found = true; master_connected = true; - ss_dassert(SERVER_IS_MASTER((*p_master_ref)->bref_backend->backend_server)); + /* assert with master_host */ + ss_dassert(master_host && ((*p_master_ref)->bref_backend->backend_server == master_host->backend_server) && SERVER_MASTER); } /** New session or master failure case */ else @@ -1547,8 +1565,9 @@ static bool select_connect_backend_servers( b->backend_conn_count))); } #endif + /* assert with master_host */ ss_dassert(!master_connected || - SERVER_IS_MASTER((*p_master_ref)->bref_backend->backend_server)); + (master_host && ((*p_master_ref)->bref_backend->backend_server == master_host->backend_server) && SERVER_MASTER)); /** * Sort the pointer list to servers according to connection counts. As * a consequence those backends having least connections are in the @@ -1613,13 +1632,15 @@ static bool select_connect_backend_servers( STRSRVSTATUS(b->backend_server), b->backend_conn_count, router->bitmask))); - + if (SERVER_IS_RUNNING(b->backend_server) && ((b->backend_server->status & router->bitmask) == router->bitvalue)) { + /* check also for relay servers and don't take the master_host */ if (slaves_found < max_nslaves && - SERVER_IS_SLAVE(b->backend_server)) + (SERVER_IS_SLAVE(b->backend_server) || SERVER_IS_RELAY_SERVER(b->backend_server)) && + (master_host != NULL && (b->backend_server != master_host->backend_server))) { slaves_found += 1; @@ -1680,7 +1701,8 @@ static bool select_connect_backend_servers( } } } - else if (SERVER_IS_MASTER(b->backend_server)) + /* take the master_host for master */ + else if (master_host && (b->backend_server == master_host->backend_server)) { *p_master_ref = &backend_ref[i]; @@ -1747,8 +1769,9 @@ static bool select_connect_backend_servers( b->backend_server->port, b->backend_conn_count))); } + /* assert with master_host */ ss_dassert(!master_connected || - SERVER_IS_MASTER((*p_master_ref)->bref_backend->backend_server)); + (master_host && ((*p_master_ref)->bref_backend->backend_server == master_host->backend_server) && SERVER_MASTER)); #endif /** @@ -2977,3 +3000,42 @@ static int router_handle_state_switch( return_rc: return rc; } + +static BACKEND *get_root_master(backend_ref_t *servers, int router_nservers) { + int i = 0; + BACKEND * master_host = NULL; + + /* (1) find root server(s) with lowest replication depth level */ + for (i = 0; i< router_nservers; i++) { + BACKEND* b = NULL; + b = servers[i].bref_backend; + if (b && SERVER_IS_RUNNING(b->backend_server)) { + if (master_host && b->backend_server->depth < master_host->backend_server->depth) { + master_host = b; + } else { + if (master_host == NULL) { + master_host = b; + } + } + } + } + + /* (2) get the status of server(s) with lowest replication level and check it against SERVER_MASTER bitvalue */ + if (master_host) { + int found = 0; + for (i = 0; ibackend_server) && (b->backend_server->depth == master_host->backend_server->depth)) { + if (b->backend_server->status & SERVER_MASTER) { + master_host = b; + found = 1; + } + } + } + if (!found) + master_host = NULL; + } + + return master_host; +}