fix bug: read-only server should choose from active backends

This commit is contained in:
jingxiaobing 2018-06-14 15:47:29 +08:00
parent d1e8104da3
commit 692aa2780e
3 changed files with 13 additions and 77 deletions

View File

@ -1615,13 +1615,13 @@ proxy_get_backend_ndx(network_mysqld_con *con, int type, gboolean force_slave)
int idx;
if (type == BACKEND_TYPE_RO) {
if (force_slave) {
idx = network_backends_get_ro_ndx(g->backends, BACKEND_ALGO_ROUND_ROBIN);
idx = network_backends_get_ro_ndx(g->backends);
} else {
int x = g_random_int_range(0, 100);
if (x < con->config->read_master_percentage) {
idx = network_backends_get_rw_ndx(g->backends);
} else {
idx = network_backends_get_ro_ndx(g->backends, BACKEND_ALGO_ROUND_ROBIN);
idx = network_backends_get_ro_ndx(g->backends);
}
g_debug(G_STRLOC "x: %d, read_master_percentage: %d, read: %d\n",
x, con->config->read_master_percentage, idx);

View File

@ -500,84 +500,26 @@ network_group_update(network_group_t *gp)
g_list_free(backends);
}
static int
backends_get_ro_ndx_round_robin(network_backends_t *bs)
/* round robin choose read only backend */
int network_backends_get_ro_ndx(network_backends_t *bs)
{
int ro_index = 0, remainder = 0;
if (bs->ro_server_num > 0) {
remainder = (bs->read_count++) % bs->ro_server_num;
}
GArray* active_ro_indices = g_array_sized_new(FALSE, TRUE, sizeof(int), 4);
int count = network_backends_count(bs);
int i = 0;
for (i = 0; i < count; i++) {
network_backend_t *backend = network_backends_get(bs, i);
if ((backend->type == BACKEND_TYPE_RO)
&& (backend->state == BACKEND_STATE_UP || backend->state == BACKEND_STATE_UNKNOWN)) {
if (ro_index == remainder) {
break;
}
ro_index++;
g_array_append_val(active_ro_indices, i);
}
}
return i < count ? i : -1;
}
static int
backends_get_ro_ndx_first(network_backends_t *bs)
{
int i = 0;
int count = network_backends_count(bs);
for (i = 0; i < count; i++) {
network_backend_t *backend = network_backends_get(bs, i);
if ((backend->type == BACKEND_TYPE_RO)
&& (backend->state == BACKEND_STATE_UP || backend->state == BACKEND_STATE_UNKNOWN)) {
return i;
}
}
return -1;
}
static int
backends_get_ro_ndx_random(network_backends_t *bs)
{
int count = network_backends_count(bs);
int ndx = g_random_int_range(0, count);
network_backend_t *backend = network_backends_get(bs, ndx);
if (backend->type == BACKEND_TYPE_RO) { /* luckily run into a RO */
if (backend->state == BACKEND_STATE_UP || backend->state == BACKEND_STATE_UNKNOWN) {
return ndx;
}
} else { /* if we run into a RW, try it's neighbours */
if (ndx - 1 >= 0) {
backend = network_backends_get(bs, ndx - 1);
if ((backend->type == BACKEND_TYPE_RO)
&& (backend->state == BACKEND_STATE_UP || backend->state == BACKEND_STATE_UNKNOWN)) {
return ndx - 1;
}
} else if (ndx + 1 < count) {
if ((backend->type == BACKEND_TYPE_RO)
&& (backend->state == BACKEND_STATE_UP || backend->state == BACKEND_STATE_UNKNOWN)) {
return ndx + 1;
}
}
}
return backends_get_ro_ndx_first(bs);
}
int
network_backends_get_ro_ndx(network_backends_t *bs, backend_algo_t algo)
{
switch (algo) {
case BACKEND_ALGO_ROUND_ROBIN:
return backends_get_ro_ndx_round_robin(bs);
case BACKEND_ALGO_RANDOM:
return backends_get_ro_ndx_random(bs);
case BACKEND_ALGO_FIRST:
return backends_get_ro_ndx_first(bs);
default:
return -1;
int num = active_ro_indices->len;
int result = -1;
if (num > 0) {
result = g_array_index(active_ro_indices, int, (bs->read_count++) % num);
}
g_array_free(active_ro_indices, TRUE);
return result;
}
int

View File

@ -49,12 +49,6 @@ typedef enum {
BACKEND_TYPE_RO,
} backend_type_t;
typedef enum {
BACKEND_ALGO_ROUND_ROBIN,
BACKEND_ALGO_RANDOM,
BACKEND_ALGO_FIRST,
} backend_algo_t;
typedef struct backend_config {
GString *default_username;
GString *default_db;
@ -142,7 +136,7 @@ network_backend_t *network_group_pick_slave_backend(network_group_t *);
void network_group_get_slave_names(network_group_t *, GString *);
int network_backends_get_ro_ndx(network_backends_t *, backend_algo_t);
int network_backends_get_ro_ndx(network_backends_t *);
int network_backends_get_rw_ndx(network_backends_t *);