Пример #1
0
/**
 * swap the server connection with a connection from
 * the connection pool
 *
 * we can only switch backends if we have a authed connection in the pool.
 *
 * @return NULL if swapping failed
 *         the new backend on success
 */
network_socket *network_connection_pool_lua_swap(network_mysqld_con *con, int backend_ndx, GHashTable *pwd_table) {
	network_backend_t *backend = NULL;
	network_socket *send_sock;
	network_mysqld_con_lua_t *st = con->plugin_con_state;
//	GString empty_username = { "", 0, 0 };

	/*
	 * we can only change to another backend if the backend is already
	 * in the connection pool and connected
	 */

	backend = network_backends_get(con->srv->backends, backend_ndx);
	if (!backend) return NULL;


	/**
	 * get a connection from the pool which matches our basic requirements
	 * - username has to match
	 * - default_db should match
	 */
		
#ifdef DEBUG_CONN_POOL
	g_debug("%s: (swap) check if we have a connection for this user in the pool '%s'", G_STRLOC, con->client->response ? con->client->response->username->str: "empty_user");
#endif
       int flag = 0;
	network_connection_pool* pool = chassis_event_thread_pool(backend);
	if (NULL == (send_sock = network_connection_pool_get(pool))) {
		/**
		 * no connections in the pool
		 */
        flag = 1;
		if (NULL == (send_sock = self_connect(con, backend, pwd_table))) {
			st->backend_ndx = -1;
			return NULL;
		}
	}

	/* the backend is up and cool, take and move the current backend into the pool */
#ifdef DEBUG_CONN_POOL
	g_debug("%s: (swap) added the previous connection to the pool", G_STRLOC);
#endif
//	network_connection_pool_lua_add_connection(con);

	/* connect to the new backend */
	st->backend = backend;
//	st->backend->connected_clients++;
	st->backend_ndx = backend_ndx;
    
        if (flag == 0 && !g_atomic_int_compare_and_exchange(&st->backend->connected_clients, 0, 0)) {
            g_atomic_int_dec_and_test(&st->backend->connected_clients);
            //g_critical("pool_lua_swap:%08x's connected_clients is %d\n", backend,  backend->connected_clients);
        }

	return send_sock;
}
Пример #2
0
int backend_load_balance_get(network_mysqld_con* con) {
       int ret = -1;
       gint i, load_value, count, flag = 0;
       double cv, connect_value;
       network_backend_t* backend;
       network_connection_pool* pool;

       if(con->config->max_connections == 0) return ret;
       network_backends_t* backends = con->srv->priv->backends;
       count = network_backends_count(backends);
       load_value = con->config->max_connections;

       for(i = 0; i < count; i++) {
              backend = network_backends_get(backends, i);
              if (backend == NULL) continue;
              pool = chassis_event_thread_pool(backend);
              if (pool == NULL) continue;
              if (backend->type == BACKEND_TYPE_RO && backend->state == BACKEND_STATE_UP && backend->connected_clients >= load_value) {
                     flag = 1;
                     connect_value = backend->connected_clients / (double)backend->weight;
                     break;
              }
       }
       if(flag == 0) return ret;
       for(i = 0; i < count; i++) {
              backend = network_backends_get(backends, i);
              if (backend == NULL) continue;
              pool = chassis_event_thread_pool(backend);
              if (pool == NULL) continue;
              if (backend->type == BACKEND_TYPE_RO && backend->state == BACKEND_STATE_UP) {
                     cv = backend->connected_clients / (double)backend->weight;
                     if(cv <= connect_value) {
                            ret = i;
                            connect_value = cv;
                     }
              }
       }

       return ret;
}
Пример #3
0
/**
 * swap the server connection with a connection from
 * the connection pool
 *
 * we can only switch backends if we have a authed connection in the pool.
 *
 * @return NULL if swapping failed
 *         the new backend on success
 */
network_socket *network_connection_pool_lua_swap(network_mysqld_con *con, int backend_ndx) {
	network_backend_t *backend = NULL;
	network_socket *send_sock;
	network_mysqld_con_lua_t *st = con->plugin_con_state;
	chassis_private *g = con->srv->priv;
//	GString empty_username = { "", 0, 0 };

	/*
	 * we can only change to another backend if the backend is already
	 * in the connection pool and connected
	 */

	backend = network_backends_get(g->backends, backend_ndx);
	if (!backend) return NULL;


	/**
	 * get a connection from the pool which matches our basic requirements
	 * - username has to match
	 * - default_db should match
	 */
		
#ifdef DEBUG_CONN_POOL
	g_debug("%s: (swap) check if we have a connection for this user in the pool '%s'", G_STRLOC, con->client->response ? con->client->response->username->str: "empty_user");
#endif
	network_connection_pool* pool = chassis_event_thread_pool(backend);
	if (NULL == (send_sock = network_connection_pool_get(pool))) {
		/**
		 * no connections in the pool
		 */
		if (NULL == (send_sock = self_connect(con, backend))) {
			st->backend_ndx = -1;
			return NULL;
		}
	}

	/* the backend is up and cool, take and move the current backend into the pool */
#ifdef DEBUG_CONN_POOL
	g_debug("%s: (swap) added the previous connection to the pool", G_STRLOC);
#endif
//	network_connection_pool_lua_add_connection(con);

	/* connect to the new backend */
	st->backend = backend;
//	st->backend->connected_clients++;
	st->backend_ndx = backend_ndx;

	return send_sock;
}
Пример #4
0
/**
 * get proxy.global.backends[ndx]
 *
 * get the backend from the array of mysql backends.
 *
 * @return nil or the backend
 * @see proxy_backend_get
 */
static int proxy_backends_get(lua_State *L) {
	network_backend_t *backend;
	network_backend_t **backend_p;

	network_backends_t *bs = *(network_backends_t **)luaL_checkself(L);
	int backend_ndx = luaL_checkinteger(L, 2) - 1; /** lua is indexes from 1, C from 0 */

	/* check that we are in range for a _int_ */
	if (NULL == (backend = network_backends_get(bs, backend_ndx))) {
		lua_pushnil(L);

		return 1;
	}

	backend_p = lua_newuserdata(L, sizeof(backend)); /* the table underneath proxy.global.backends[ndx] */
	*backend_p = backend;

	network_backend_lua_getmetatable(L);
	lua_setmetatable(L, -2);

	return 1;
}
Пример #5
0
int idle_rw(network_mysqld_con* con) {
       int ret = -1;
       guint i;

       network_backends_t* backends = con->srv->priv->backends;

       guint count = network_backends_count(backends);
       for (i = 0; i < count; ++i) {
              network_backend_t* backend = network_backends_get(backends, i);
              if (backend == NULL) continue;

              network_connection_pool* pool = chassis_event_thread_pool(backend);
              if (pool == NULL) continue;

              if (backend->type == BACKEND_TYPE_RW && backend->state == BACKEND_STATE_UP) {
                     ret = i;
                     break;
              }
       }

       return ret;
}
Пример #6
0
int idle_ro(network_mysqld_con* con) {
       int max_conns = -1;
       guint i;

       network_backends_t* backends = con->srv->priv->backends;

       guint count = network_backends_count(backends);
       for(i = 0; i < count; ++i) {
              network_backend_t* backend = network_backends_get(backends, i);
              if (backend == NULL) continue;

              network_connection_pool* pool = chassis_event_thread_pool(backend);
              if (pool == NULL) continue;

              if (backend->type == BACKEND_TYPE_RO && backend->state == BACKEND_STATE_UP) {
                     if (max_conns == -1 || backend->connected_clients < max_conns) {
                            max_conns = backend->connected_clients;
                     }
              }
       }

       return max_conns;
}
Пример #7
0
int wrr_ro(network_mysqld_con *con) {
       guint i, j;
       network_backends_t* backends = con->srv->priv->backends;
       g_wrr_poll* rwsplit = backends->global_wrr;
       guint ndx_num = network_backends_count(backends);
       if (rwsplit->next_ndx >= ndx_num)
              rwsplit->next_ndx = 0;
       gint backend_ndx = backend_load_balance_get(con);
       if(0 < backend_ndx) return backend_ndx;
       // set max weight if no init
       if (rwsplit->max_weight == 0) {
              for(i = 0; i < ndx_num; ++i) {
                     network_backend_t* backend = network_backends_get(backends, i);
                     if (backend == NULL || backend->state != BACKEND_STATE_UP) continue;
                     if (rwsplit->max_weight < backend->weight) {
                            rwsplit->max_weight = backend->weight;
                            rwsplit->cur_weight = backend->weight;
                     }
              }
       }

       guint max_weight = rwsplit->max_weight;
       gint cur_weight = rwsplit->cur_weight;
       guint next_ndx   = rwsplit->next_ndx;

       // get backend index by slave wrr
       gint ndx = -1;
       for(i = 0; i < ndx_num; ++i) {
              network_backend_t* backend = network_backends_get(backends, next_ndx);
              if (backend == NULL) goto next;

              network_connection_pool* pool = chassis_event_thread_pool(backend);
              if (pool == NULL) goto next;

              if (backend->type == BACKEND_TYPE_RO && backend->weight >= cur_weight) {
                     if(backend->state == BACKEND_STATE_UP) {
                            ndx = next_ndx;
                     }else {
                            for(j = 0; j < ndx_num; ++j) {
                                   network_backend_t* b = network_backends_get(backends, j);
                                   if(b == NULL) continue;
                                   network_connection_pool* p = chassis_event_thread_pool(b);
                                   if(p == NULL) continue;
                                   if(b->type == BACKEND_TYPE_RO && b->state == BACKEND_STATE_UP) ndx = j;
                            }
                     }
              }
next:
              if (next_ndx >= ndx_num - 1) {
                     --cur_weight;
                     next_ndx = 0;

                     if (cur_weight <= 0) cur_weight = max_weight;
              } else {
                     ++next_ndx;
              }

              if (ndx != -1) break;
       }
       rwsplit->cur_weight = cur_weight;
       rwsplit->next_ndx = next_ndx;
       return ndx;
}
Пример #8
0
/**
 * swap the server connection with a connection from
 * the connection pool
 *
 * we can only switch backends if we have a authed connection in the pool.
 *
 * @return NULL if swapping failed
 *         the new backend on success
 */
network_socket* network_connection_pool_lua_swap(network_mysqld_con *con, int backend_ndx, int need_keep_conn, int *err) {
	network_backend_t *backend = NULL;
	network_socket *send_sock;
       network_connection_pool *pool, *second_pool;
	network_mysqld_con_lua_t *st = con->plugin_con_state;
	chassis_private *g = con->srv->priv;

	/*
	 * we can only change to another backend if the backend is already
	 * in the connection pool and connected
	 */

	backend = network_backends_get(g->backends, backend_ndx);
	if (!backend) return NULL;


	/**
	 * get a connection from the pool which matches our basic requirements
	 * - username has to match
	 * - default_db should match
	 */

#ifdef DEBUG_CONN_POOL
	g_debug("%s: (swap) check if we have a connection for this user in the pool '%s'", G_STRLOC, con->client->response ? con->client->response->username->str: "empty_user");
#endif
       if(need_keep_conn == 0) {
              pool = chassis_event_thread_pool(backend);
              send_sock = network_connection_pool_get(pool);
              if(send_sock == NULL) {
                     second_pool = chassis_event_thread_secondpool(backend);
                     send_sock = network_expiretime_connection_pool_get(second_pool, con);
              }
       }else {
              second_pool = chassis_event_thread_secondpool(backend);
              send_sock = network_connection_secondpool_get(second_pool, con);
              if(send_sock == NULL) g_message("%s:the connection need keep, but it's not in the pool now.", G_STRLOC);
       }
	if (NULL == send_sock ) {
		/**
		 * no connections in the pool
		 */
              if ((con->config->max_connections <= 0) || (backend->connected_clients < con->config->max_connections)) {
                     if (NULL == (send_sock = self_connect(con, backend))) {
                            st->backend_ndx = -1;
                            return NULL;
                     }
              } else {
                     st->backend_ndx = -1;
                     *err = -1;
                     return NULL;
              }
	}

	/* the backend is up and cool, take and move the current backend into the pool */
#ifdef DEBUG_CONN_POOL
	g_debug("%s: (swap) added the previous connection to the pool", G_STRLOC);
#endif

	/* connect to the new backend */
	st->backend = backend;
	g_atomic_int_inc(&(st->backend->connected_clients));
	st->backend_ndx = backend_ndx;

	return send_sock;
}
/**
 * 测试zabbix没有启动的情况
 * @return
 */
void test_admin_backend_mange_Add(void) {
	/** 初始化内存变量*/
	network_backend_t *b = NULL;
	chassis *srv1 = g_new0(chassis, 1);
	srv1->priv = g_new0(chassis_private, 1);
	srv1->priv->backends  = network_backends_new();
	srv1->xml_filename = "test_config.xml";
	network_backends_add(srv1->priv->backends, "X.X.X.X:3306#2#UP", BACKEND_TYPE_RW);
	b = network_backends_get(srv1->priv->backends, 0);
	g_mutex_init(&(b->mutex[0]));
	g_mutex_init(&(b->mutex[1]));

	network_backends_add(srv1->priv->backends, "X.X.X.X:3306#3#UP", BACKEND_TYPE_RO);
	b = network_backends_get(srv1->priv->backends, 1);
	g_mutex_init(&(b->mutex[0]));
	g_mutex_init(&(b->mutex[1]));

	network_mysqld_con *con = network_mysqld_con_new();
	con->client = network_socket_new();
	con->srv = srv1;
	con->srv->detect_threads = g_ptr_array_new();
	//network_mysqld_add_connection(srv1, con);

	gchar *cmd = g_strdup("addBackend --backend=X.X.X.X:3306");
	g_assert_cmpint(COMMAND_PROCESS_ERROR, ==, admin_command_process(con, cmd));
	g_free(cmd);
	cmd = NULL;

	cmd = g_strdup("addBackend");
        g_assert_cmpint(COMMAND_PROCESS_ERROR, ==, admin_command_process(con, cmd));
        g_free(cmd);
        cmd = NULL;

	g_assert(COMMAND_NO_QUERY_SPECIFIED == admin_command_process(con, NULL));

	cmd = g_strdup("addBackend --backend=X.X.X.X:3307");
	g_assert(COMMAND_PROCESS_ERROR == admin_command_process(con, cmd));
	g_free(cmd);
	cmd = NULL;

	cmd = g_strdup("addBackend --backend=X.X.X.X:3307#1#up --bktype=rw");
        g_assert(COMMAND_PROCESS_ERROR == admin_command_process(con, cmd));
        g_free(cmd);
        cmd = NULL;

	cmd = g_strdup("addBackend --backend=X.X.X.X:3307 --bktype=ro");
        g_assert(COMMAND_PROCESS_SUCCESS == admin_command_process(con, cmd));
	network_backend_t *backend = network_backends_get_by_name(srv1->priv->backends, "X.X.X.X:3307");
	g_assert(backend);
	g_free(cmd);
	cmd = NULL;

	cmd = g_strdup("addBackend --backend=192.1968.x.xx:3308");
	g_assert(COMMAND_PROCESS_ERROR == admin_command_process(con, cmd));
	g_free(cmd);
	cmd = NULL;

	cmd = g_strdup("addBackend --backends=X.X.X.X:3308");
	g_assert(COMMAND_PROCESS_ERROR == admin_command_process(con, cmd));
	g_free(cmd);
	cmd = NULL;

	cmd = g_strdup("addBackend --backend=X.X.X.X:103307");
	g_assert(COMMAND_PROCESS_ERROR == admin_command_process(con, cmd));
	g_free(cmd);
	cmd = NULL;

	cmd = g_strdup("addBackends --backend=X.X.X.X:3308");
	g_assert(COMMAND_NOT_SUPPORT == admin_command_process(con, cmd));
	g_free(cmd);
	cmd = NULL;

//	g_ptr_array_free(con->srv->detect_threads, TRUE);
//	con->srv->detect_threads = NULL;

	//network_mysqld_con_free(con);
	//con = NULL;

	//network_backends_free(srv1->priv->backends);
	//srv1->priv->backends = NULL;

	//g_free(srv1->priv);
	//srv1->priv = NULL;

	//g_free(srv1);
	//srv1 = NULL;
}
Пример #10
0
void test_adjust_backend(void) {
	network_backend_t *b = NULL;
	guint health = 0;

	network_backends_add(srv1->priv->backends, "192.168.x.x:3306#2#UN", BACKEND_TYPE_RO);
	network_backends_add(srv1->priv->backends, "192.168.x.x:3306#4#UN", BACKEND_TYPE_RO);
	network_backends_add(srv1->priv->backends, "192.168.x.x:3306#1#UN", BACKEND_TYPE_RO);

	b = network_backends_get(srv1->priv->backends, 0);
	adjust_backend(BACKEND_STATE_UP, srv1, b);
	g_assert_cmpint(b->state, ==, BACKEND_STATE_UP);
	health = b->health_check.rise + b->health_check.fall - 1;
	g_assert_cmpint(b->health_check.health, == , health);
	g_assert_cmpint(b->type, ==, BACKEND_TYPE_RW);

	adjust_backend(BACKEND_STATE_DOWN, srv1, b);
	g_assert_cmpint(b->state, ==, BACKEND_STATE_UP);
	health--;
	g_assert_cmpint(b->health_check.health, == , health);
	g_assert_cmpint(b->type, ==, BACKEND_TYPE_RW);

	adjust_backend(BACKEND_STATE_UP, srv1, b);
	g_assert_cmpint(b->state, ==, BACKEND_STATE_UP);
	health = b->health_check.rise + b->health_check.fall - 1;
	g_assert_cmpint(b->health_check.health, == , health);
	g_assert_cmpint(b->type, ==, BACKEND_TYPE_RW);

	adjust_backend(BACKEND_STATE_DOWN, srv1, b);
	g_assert_cmpint(b->state, ==, BACKEND_STATE_UP);
	health--;
	g_assert_cmpint(b->health_check.health, == , health);
	g_assert_cmpint(b->type, ==, BACKEND_TYPE_RW);

	adjust_backend(BACKEND_STATE_DOWN, srv1, b);
	g_assert_cmpint(b->state, ==, BACKEND_STATE_UP);
	health--;
	g_assert_cmpint(b->health_check.health, == , health);
	g_assert_cmpint(b->type, ==, BACKEND_TYPE_RW);

	adjust_backend(BACKEND_STATE_DOWN, srv1, b);
	g_assert_cmpint(b->state, ==, BACKEND_STATE_DOWN);
	health = 0;
	g_assert_cmpint(b->health_check.health, == , health);
	g_assert_cmpint(b->type, ==, BACKEND_TYPE_RO);

	adjust_backend(BACKEND_STATE_UP, srv1, b);
	g_assert_cmpint(b->state, ==, BACKEND_STATE_DOWN);
	health++;
	g_assert_cmpint(b->health_check.health, == , health);
	g_assert_cmpint(b->type, ==, BACKEND_TYPE_RO);

	adjust_backend(BACKEND_STATE_DOWN, srv1, b);
	g_assert_cmpint(b->state, ==, BACKEND_STATE_DOWN);
	health = 0;
	g_assert_cmpint(b->health_check.health, == , health);
	g_assert_cmpint(b->type, ==, BACKEND_TYPE_RO);

	adjust_backend(BACKEND_STATE_UP, srv1, b);
	g_assert_cmpint(b->state, ==, BACKEND_STATE_DOWN);
	health++;
	g_assert_cmpint(b->health_check.health, == , health);
	g_assert_cmpint(b->type, ==, BACKEND_TYPE_RO);

	adjust_backend(BACKEND_STATE_UP, srv1, b);
	g_assert_cmpint(b->state, ==, BACKEND_STATE_UP);
	health = b->health_check.rise + b->health_check.fall - 1;
	g_assert_cmpint(b->health_check.health, == , health);
	g_assert_cmpint(b->type, ==, BACKEND_TYPE_RW);

	network_backends_free(srv1->priv->backends);
	srv1->priv->backends = NULL;
}