Cluster node exports admin-mysql_ifaces

When a cluster node (client) connects to another cluster node, it
advertises its UUID but also exports its `admin-mysql_ifaces` .
The receiving cluster can use this information to try to guess how
to connect to the node that initialized the connection, for example
to collect metrics.
This is visible in table `stats_proxysql_servers_clients_status` .
pull/3305/head
René Cannaò 5 years ago
parent 1f03bbf09f
commit 86c95dbb18

@ -51,9 +51,11 @@ class ProxySQL_Node_Address {
uint64_t hash; // unused for now
char *uuid;
char *hostname;
char *admin_mysql_ifaces;
uint16_t port;
ProxySQL_Node_Address(char *h, uint16_t p) {
hostname = strdup(h);
admin_mysql_ifaces = NULL;
port = p;
uuid = NULL;
hash = 0;
@ -61,6 +63,7 @@ class ProxySQL_Node_Address {
~ProxySQL_Node_Address() {
if (hostname) free(hostname);
if (uuid) free(uuid);
if (admin_mysql_ifaces) free(admin_mysql_ifaces);
}
};
@ -237,6 +240,9 @@ class ProxySQL_Cluster {
pthread_mutex_t update_mysql_users_mutex;
pthread_mutex_t update_mysql_variables_mutex;
pthread_mutex_t update_proxysql_servers_mutex;
// this records the interface that Admin is listening to
pthread_mutex_t admin_mysql_ifaces_mutex;
char *admin_mysql_ifaces;
int cluster_check_interval_ms;
int cluster_check_status_frequency;
int cluster_mysql_query_rules_diffs_before_sync;
@ -261,6 +267,7 @@ class ProxySQL_Cluster {
void get_credentials(char **, char **);
void set_username(char *);
void set_password(char *);
void set_admin_mysql_ifaces(char *);
bool Update_Node_Metrics(char * _h, uint16_t _p, MYSQL_RES *_r, unsigned long long _response_time) {
return nodes.Update_Node_Metrics(_h, _p, _r, _response_time);
}

@ -493,7 +493,7 @@ static int http_handler(void *cls, struct MHD_Connection *connection, const char
#define ADMIN_SQLITE_TABLE_RUNTIME_PROXYSQL_SERVERS "CREATE TABLE runtime_proxysql_servers (hostname VARCHAR NOT NULL , port INT NOT NULL DEFAULT 6032 , weight INT CHECK (weight >= 0) NOT NULL DEFAULT 0 , comment VARCHAR NOT NULL DEFAULT '' , PRIMARY KEY (hostname, port) )"
#define STATS_SQLITE_TABLE_PROXYSQL_SERVERS_CLIENTS_STATUS "CREATE TABLE stats_proxysql_servers_clients_status (uuid VARCHAR NOT NULL , hostname VARCHAR NOT NULL , port INT NOT NULL , last_seen_at INT NOT NULL , PRIMARY KEY (uuid, hostname, port) )"
#define STATS_SQLITE_TABLE_PROXYSQL_SERVERS_CLIENTS_STATUS "CREATE TABLE stats_proxysql_servers_clients_status (uuid VARCHAR NOT NULL , hostname VARCHAR NOT NULL , port INT NOT NULL , admin_mysql_ifaces VARCHAR NOT NULL , last_seen_at INT NOT NULL , PRIMARY KEY (uuid, hostname, port) )"
#define STATS_SQLITE_TABLE_PROXYSQL_SERVERS_STATUS "CREATE TABLE stats_proxysql_servers_status (hostname VARCHAR NOT NULL , port INT NOT NULL DEFAULT 6032 , weight INT CHECK (weight >= 0) NOT NULL DEFAULT 0 , master VARCHAR NOT NULL , global_version INT NOT NULL , check_age_us INT NOT NULL , ping_time_us INT NOT NULL, checks_OK INT NOT NULL , checks_ERR INT NOT NULL , PRIMARY KEY (hostname, port) )"
@ -1221,28 +1221,43 @@ bool admin_handler_command_proxysql(char *query_no_space, unsigned int query_no_
sess->client_myds->shut_soft();
return false;
}
if (query_no_space_length==l+36) {
if (query_no_space_length >= l+36+2) {
uuid_t uu;
if (uuid_parse(query_no_space+l, uu)==0) {
char *A_uuid = NULL;
char *B_interface = NULL;
c_split_2(query_no_space+l, " ", &A_uuid, &B_interface); // we split the value
if (uuid_parse(A_uuid, uu)==0 && B_interface && strlen(B_interface)) {
proxy_info("Received PROXYSQL CLUSTER_NODE_UUID from %s:%d : %s\n", sess->client_myds->addr.addr, sess->client_myds->addr.port, query_no_space+l);
if (sess->proxysql_node_address==NULL) {
sess->proxysql_node_address = new ProxySQL_Node_Address(sess->client_myds->addr.addr, sess->client_myds->addr.port);
sess->proxysql_node_address->uuid = strdup(query_no_space+l);
proxy_info("Created new link with Cluster node %s:%d : %s\n", sess->client_myds->addr.addr, sess->client_myds->addr.port, query_no_space+l);
sess->proxysql_node_address->uuid = strdup(A_uuid);
if (sess->proxysql_node_address->admin_mysql_ifaces) {
free(sess->proxysql_node_address->admin_mysql_ifaces);
}
sess->proxysql_node_address->admin_mysql_ifaces = strdup(B_interface);
proxy_info("Created new link with Cluster node %s:%d : %s at interface %s\n", sess->client_myds->addr.addr, sess->client_myds->addr.port, A_uuid, B_interface);
SPA->send_MySQL_OK(&sess->client_myds->myprot, NULL);
free(A_uuid);
free(B_interface);
return false;
} else {
if (strcmp(query_no_space+l, sess->proxysql_node_address->uuid)) {
proxy_error("Cluster node %s:%d is sending a new UUID : %s . Former UUID : %s . Exiting client\n", sess->client_myds->addr.addr, sess->client_myds->addr.port, query_no_space+l, sess->proxysql_node_address->uuid);
if (strcmp(A_uuid, sess->proxysql_node_address->uuid)) {
proxy_error("Cluster node %s:%d is sending a new UUID : %s . Former UUID : %s . Exiting client\n", sess->client_myds->addr.addr, sess->client_myds->addr.port, A_uuid, sess->proxysql_node_address->uuid);
SPA->send_MySQL_ERR(&sess->client_myds->myprot, (char *)"Received PROXYSQL CLUSTER_NODE_UUID with a new UUID not matching the previous one");
sess->client_myds->shut_soft();
free(A_uuid);
free(B_interface);
return false;
} else {
proxy_info("Cluster node %s:%d is sending again its UUID : %s\n", sess->client_myds->addr.addr, sess->client_myds->addr.port, query_no_space+l);
proxy_info("Cluster node %s:%d is sending again its UUID : %s\n", sess->client_myds->addr.addr, sess->client_myds->addr.port, A_uuid);
SPA->send_MySQL_OK(&sess->client_myds->myprot, NULL);
free(A_uuid);
free(B_interface);
return false;
}
}
free(A_uuid);
free(B_interface);
return false;
} else {
proxy_warning("Received PROXYSQL CLUSTER_NODE_UUID from %s:%d with invalid format: %s . Exiting client\n", sess->client_myds->addr.addr, sess->client_myds->addr.port, query_no_space+l);
@ -4802,13 +4817,15 @@ __run_query:
if (sess->proxysql_node_address) {
if (sess->client_myds->active) {
time_t now = time(NULL);
string q = "INSERT OR REPLACE INTO stats_proxysql_servers_clients_status (uuid, hostname, port, last_seen_at) VALUES (\"";
string q = "INSERT OR REPLACE INTO stats_proxysql_servers_clients_status (uuid, hostname, port, admin_mysql_ifaces, last_seen_at) VALUES (\"";
q += sess->proxysql_node_address->uuid;
q += "\",\"";
q += sess->proxysql_node_address->hostname;
q += "\",";
q += std::to_string(sess->proxysql_node_address->port);
q += ",";
q += ",\"";
q += sess->proxysql_node_address->admin_mysql_ifaces;
q += "\",";
q += std::to_string(now) + ")";
SPA->statsdb->execute(q.c_str());
}
@ -7615,6 +7632,7 @@ bool ProxySQL_Admin::set_variable(char *name, char *value) { // this is the pub
if (update_creds && variables.mysql_ifaces) {
S_amll.update_ifaces(variables.mysql_ifaces, &S_amll.ifaces_mysql);
}
GloProxyCluster->set_admin_mysql_ifaces(value);
return true;
} else {
return false;

@ -110,6 +110,10 @@ void * ProxySQL_Cluster_Monitor_thread(void *args) {
same_version = true;
std::string q = "PROXYSQL CLUSTER_NODE_UUID ";
q += GloVars.uuid;
q += " ";
pthread_mutex_lock(&GloProxyCluster->admin_mysql_ifaces_mutex);
q += GloProxyCluster->admin_mysql_ifaces;
pthread_mutex_unlock(&GloProxyCluster->admin_mysql_ifaces_mutex);
proxy_info("Cluster: sending CLUSTER_NODE_UUID %s to peer %s:%d\n", GloVars.uuid, node->hostname, node->port);
rc_query = mysql_query(conn, q.c_str());
} else {
@ -2586,6 +2590,9 @@ ProxySQL_Cluster::ProxySQL_Cluster() {
pthread_mutex_init(&update_mysql_servers_mutex,NULL);
pthread_mutex_init(&update_mysql_users_mutex,NULL);
pthread_mutex_init(&update_proxysql_servers_mutex,NULL);
pthread_mutex_init(&update_mysql_variables_mutex,NULL);
pthread_mutex_init(&admin_mysql_ifaces_mutex,NULL);
admin_mysql_ifaces = strdup((char *)""); // always initialized
cluster_username = strdup((char *)"");
cluster_password = strdup((char *)"");
cluster_check_interval_ms = 1000;
@ -2611,6 +2618,10 @@ ProxySQL_Cluster::~ProxySQL_Cluster() {
free(cluster_password);
cluster_password = NULL;
}
if (admin_mysql_ifaces) {
free(admin_mysql_ifaces);
admin_mysql_ifaces = NULL;
}
}
// this function returns credentials to the caller, used by monitoring threads
@ -2635,6 +2646,13 @@ void ProxySQL_Cluster::set_password(char *_password) {
pthread_mutex_unlock(&mutex);
}
void ProxySQL_Cluster::set_admin_mysql_ifaces(char *value) {
pthread_mutex_lock(&admin_mysql_ifaces_mutex);
free(admin_mysql_ifaces);
admin_mysql_ifaces=strdup(value);
pthread_mutex_unlock(&admin_mysql_ifaces_mutex);
}
void ProxySQL_Cluster::print_version() {
fprintf(stderr,"Standard ProxySQL Cluster rev. %s -- %s -- %s\n", PROXYSQL_CLUSTER_VERSION, __FILE__, __TIMESTAMP__);
};

Loading…
Cancel
Save