Implementation of table stats_proxysql_servers_clients_status and PROXYSQL CLUSTER_NODE_UUID command

pull/3305/head
René Cannaò 5 years ago
parent 69fb384deb
commit a592402902

@ -239,6 +239,7 @@ class MySQL_Session
Session_Regex **match_regexes;
void *ldap_ctx;
ProxySQL_Node_Address * proxysql_node_address; // this is used ONLY for Admin, and only if the other party is another proxysql instance part of a cluster
// this variable is relevant only if status == SETTING_VARIABLE
enum variable_name changing_variable_idx;

@ -444,6 +444,7 @@ class MySQL_ResultSet;
class Query_Processor_Output;
class MySrvC;
class Web_Interface_plugin;
class ProxySQL_Node_Address;
#endif /* PROXYSQL_CLASSES */
//#endif /* __cplusplus */

@ -502,6 +502,7 @@ MySQL_Session::MySQL_Session() {
last_HG_affected_rows = -1; // #1421 : advanced support for LAST_INSERT_ID()
ldap_ctx = NULL;
proxysql_node_address = NULL;
}
void MySQL_Session::init() {
@ -599,6 +600,10 @@ MySQL_Session::~MySQL_Session() {
GloMyLdapAuth->ldap_ctx_free(ldap_ctx);
ldap_ctx = NULL;
}
if (proxysql_node_address) {
delete proxysql_node_address;
proxysql_node_address = NULL;
}
}

@ -493,6 +493,8 @@ 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_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) )"
#define STATS_SQLITE_TABLE_PROXYSQL_SERVERS_METRICS "CREATE TABLE stats_proxysql_servers_metrics (hostname VARCHAR NOT NULL , port INT NOT NULL DEFAULT 6032 , weight INT CHECK (weight >= 0) NOT NULL DEFAULT 0 , comment VARCHAR NOT NULL DEFAULT '' , response_time_ms INT NOT NULL , Uptime_s INT NOT NULL , last_check_ms INT NOT NULL , Queries INT NOT NULL , Client_Connections_connected INT NOT NULL , Client_Connections_created INT NOT NULL , PRIMARY KEY (hostname, port) )"
@ -1211,6 +1213,50 @@ bool admin_handler_command_kill_connection(char *query_no_space, unsigned int qu
* return true if the command is not a valid one and needs to be executed by SQLite (that will return an error)
*/
bool admin_handler_command_proxysql(char *query_no_space, unsigned int query_no_space_length, MySQL_Session *sess, ProxySQL_Admin *pa) {
if (!(strncasecmp("PROXYSQL CLUSTER_NODE_UUID ", query_no_space, strlen("PROXYSQL CLUSTER_NODE_UUID ")))) {
int l = strlen("PROXYSQL CLUSTER_NODE_UUID ");
if (sess->client_myds->addr.port == 0) {
proxy_warning("Received PROXYSQL CLUSTER_NODE_UUID not from TCP socket. Exiting client\n");
SPA->send_MySQL_ERR(&sess->client_myds->myprot, (char *)"Received PROXYSQL CLUSTER_NODE_UUID not from TCP socket");
sess->client_myds->shut_soft();
return false;
}
if (query_no_space_length==l+36) {
uuid_t uu;
if (uuid_parse(query_no_space+l, uu)==0) {
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);
SPA->send_MySQL_OK(&sess->client_myds->myprot, NULL);
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);
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();
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);
SPA->send_MySQL_OK(&sess->client_myds->myprot, NULL);
return false;
}
}
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);
SPA->send_MySQL_ERR(&sess->client_myds->myprot, (char *)"Received PROXYSQL CLUSTER_NODE_UUID with invalid format");
sess->client_myds->shut_soft();
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);
SPA->send_MySQL_ERR(&sess->client_myds->myprot, (char *)"Received PROXYSQL CLUSTER_NODE_UUID with invalid format");
sess->client_myds->shut_soft();
return false;
}
}
if (query_no_space_length==strlen("PROXYSQL READONLY") && !strncasecmp("PROXYSQL READONLY",query_no_space, query_no_space_length)) {
// this command enables admin_read_only , so the admin module is in read_only mode
proxy_info("Received PROXYSQL READONLY command\n");
@ -4623,6 +4669,20 @@ __end_show_commands:
}
__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 (\"";
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 += std::to_string(now) + ")";
SPA->statsdb->execute(q.c_str());
}
}
if (run_query) {
ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa;
if (sess->session_type == PROXYSQL_SESSION_ADMIN) { // no stats
@ -5418,6 +5478,7 @@ bool ProxySQL_Admin::init() {
insert_into_tables_defs(tables_defs_stats,"stats_proxysql_servers_checksums", STATS_SQLITE_TABLE_PROXYSQL_SERVERS_CHECKSUMS);
insert_into_tables_defs(tables_defs_stats,"stats_proxysql_servers_metrics", STATS_SQLITE_TABLE_PROXYSQL_SERVERS_METRICS);
insert_into_tables_defs(tables_defs_stats,"stats_proxysql_servers_status", STATS_SQLITE_TABLE_PROXYSQL_SERVERS_STATUS);
insert_into_tables_defs(tables_defs_stats,"stats_proxysql_servers_clients_status", STATS_SQLITE_TABLE_PROXYSQL_SERVERS_CLIENTS_STATUS);
// upgrade mysql_servers if needed (upgrade from previous version)
disk_upgrade_mysql_servers();

@ -108,6 +108,10 @@ void * ProxySQL_Cluster_Monitor_thread(void *args) {
if (strcmp(row[0], PROXYSQL_VERSION)==0) {
proxy_info("Cluster: clustering with peer %s:%d . Remote version: %s . Self version: %s\n", node->hostname, node->port, row[0], PROXYSQL_VERSION);
same_version = true;
std::string q = "PROXYSQL CLUSTER_NODE_UUID ";
q += GloVars.uuid;
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 {
proxy_warning("Cluster: different ProxySQL version with peer %s:%d . Remote: %s . Self: %s\n", node->hostname, node->port, row[0], PROXYSQL_VERSION);
}

Loading…
Cancel
Save