Merge pull request #3420 from sysown/v2.2.0-3419

Closes #3419: Add cluster synchronization support for global 'ldap-%' variables and 'mysql_ldap_mapping' provided by 'ldap_auth_plugin'
pull/3451/head
René Cannaò 5 years ago committed by GitHub
commit d3c243d898
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -86,6 +86,7 @@ class ProxySQL_Node_Entry {
struct {
ProxySQL_Checksum_Value_2 admin_variables;
ProxySQL_Checksum_Value_2 mysql_variables;
ProxySQL_Checksum_Value_2 ldap_variables;
ProxySQL_Checksum_Value_2 mysql_query_rules;
ProxySQL_Checksum_Value_2 mysql_servers;
ProxySQL_Checksum_Value_2 mysql_users;
@ -116,6 +117,7 @@ class ProxySQL_Cluster_Nodes {
void get_peer_to_sync_mysql_users(char **host, uint16_t *port);
void get_peer_to_sync_mysql_variables(char **host, uint16_t *port);
void get_peer_to_sync_admin_variables(char **host, uint16_t* port);
void get_peer_to_sync_ldap_variables(char **host, uint16_t *port);
void get_peer_to_sync_proxysql_servers(char **host, uint16_t *port);
};
@ -149,12 +151,19 @@ struct p_cluster_counter {
pulled_admin_variables_success,
pulled_admin_variables_failure,
pulled_ldap_variables_success,
pulled_ldap_variables_failure,
pulled_mysql_ldap_mapping_success,
pulled_mysql_ldap_mapping_failure,
sync_conflict_mysql_query_rules_share_epoch,
sync_conflict_mysql_servers_share_epoch,
sync_conflict_proxysql_servers_share_epoch,
sync_conflict_mysql_users_share_epoch,
sync_conflict_mysql_variables_share_epoch,
sync_conflict_admin_variables_share_epoch,
sync_conflict_ldap_variables_share_epoch,
sync_delayed_mysql_query_rules_version_one,
sync_delayed_mysql_servers_version_one,
@ -162,6 +171,7 @@ struct p_cluster_counter {
sync_delayed_proxysql_servers_version_one,
sync_delayed_mysql_variables_version_one,
sync_delayed_admin_variables_version_one,
sync_delayed_ldap_variables_version_one,
__size
};
@ -225,12 +235,14 @@ class ProxySQL_Cluster {
int cluster_mysql_users_diffs_before_sync;
int cluster_proxysql_servers_diffs_before_sync;
int cluster_mysql_variables_diffs_before_sync;
int cluster_ldap_variables_diffs_before_sync;
int cluster_admin_variables_diffs_before_sync;
bool cluster_mysql_query_rules_save_to_disk;
bool cluster_mysql_servers_save_to_disk;
bool cluster_mysql_users_save_to_disk;
bool cluster_proxysql_servers_save_to_disk;
bool cluster_mysql_variables_save_to_disk;
bool cluster_ldap_variables_save_to_disk;
bool cluster_admin_variables_save_to_disk;
ProxySQL_Cluster();
~ProxySQL_Cluster();

@ -152,12 +152,14 @@ class ProxySQL_Admin {
int cluster_proxysql_servers_diffs_before_sync;
int cluster_mysql_variables_diffs_before_sync;
int cluster_admin_variables_diffs_before_sync;
int cluster_ldap_variables_diffs_before_sync;
bool cluster_mysql_query_rules_save_to_disk;
bool cluster_mysql_servers_save_to_disk;
bool cluster_mysql_users_save_to_disk;
bool cluster_proxysql_servers_save_to_disk;
bool cluster_mysql_variables_save_to_disk;
bool cluster_admin_variables_save_to_disk;
bool cluster_ldap_variables_save_to_disk;
int stats_mysql_connection_pool;
int stats_mysql_connections;
int stats_mysql_query_cache;
@ -262,6 +264,7 @@ class ProxySQL_Admin {
bool checksum_mysql_users;
bool checksum_mysql_variables;
bool checksum_admin_variables;
bool checksum_ldap_variables;
} checksum_variables;
void public_add_active_users(enum cred_username_type usertype, char *user=NULL) {
__add_active_users(usertype, user);
@ -311,6 +314,7 @@ class ProxySQL_Admin {
void flush_mysql_variables__from_memory_to_disk();
void flush_admin_variables__from_disk_to_memory();
void flush_admin_variables__from_memory_to_disk();
void flush_ldap_variables__from_memory_to_disk();
void load_mysql_servers_to_runtime();
void save_mysql_servers_from_runtime();

@ -111,6 +111,7 @@ class ProxySQL_GlobalVariables {
ProxySQL_Checksum_Value mysql_servers;
ProxySQL_Checksum_Value mysql_users;
ProxySQL_Checksum_Value mysql_variables;
ProxySQL_Checksum_Value ldap_variables;
ProxySQL_Checksum_Value proxysql_servers;
uint64_t global_checksum;
unsigned long long updates_cnt;

@ -535,17 +535,20 @@ static char * admin_variables_names[]= {
(char *)"cluster_proxysql_servers_diffs_before_sync",
(char *)"cluster_mysql_variables_diffs_before_sync",
(char *)"cluster_admin_variables_diffs_before_sync",
(char *)"cluster_ldap_variables_diffs_before_sync",
(char *)"cluster_mysql_query_rules_save_to_disk",
(char *)"cluster_mysql_servers_save_to_disk",
(char *)"cluster_mysql_users_save_to_disk",
(char *)"cluster_proxysql_servers_save_to_disk",
(char *)"cluster_mysql_variables_save_to_disk",
(char *)"cluster_admin_variables_save_to_disk",
(char *)"cluster_ldap_variables_save_to_disk",
(char *)"checksum_mysql_query_rules",
(char *)"checksum_mysql_servers",
(char *)"checksum_mysql_users",
(char *)"checksum_mysql_variables",
(char *)"checksum_admin_variables",
(char *)"checksum_ldap_variables",
(char *)"restapi_enabled",
(char *)"restapi_port",
(char *)"web_enabled",
@ -5265,17 +5268,20 @@ ProxySQL_Admin::ProxySQL_Admin() :
variables.cluster_proxysql_servers_diffs_before_sync = 3;
variables.cluster_mysql_variables_diffs_before_sync = 3;
variables.cluster_admin_variables_diffs_before_sync = 3;
variables.cluster_ldap_variables_diffs_before_sync = 3;
checksum_variables.checksum_mysql_query_rules = true;
checksum_variables.checksum_mysql_servers = true;
checksum_variables.checksum_mysql_users = true;
checksum_variables.checksum_mysql_variables = true;
checksum_variables.checksum_admin_variables = true;
checksum_variables.checksum_ldap_variables = true;
variables.cluster_mysql_query_rules_save_to_disk = true;
variables.cluster_mysql_servers_save_to_disk = true;
variables.cluster_mysql_users_save_to_disk = true;
variables.cluster_proxysql_servers_save_to_disk = true;
variables.cluster_mysql_variables_save_to_disk = true;
variables.cluster_admin_variables_save_to_disk = true;
variables.cluster_ldap_variables_save_to_disk = true;
variables.stats_mysql_connection_pool = 60;
variables.stats_mysql_connections = 60;
variables.stats_mysql_query_cache = 60;
@ -6935,6 +6941,33 @@ void ProxySQL_Admin::flush_ldap_variables___database_to_runtime(SQLite3DB *db, b
}
}
GloMyLdapAuth->wrunlock();
// update variables checksum
if (checksum_variables.checksum_ldap_variables) {
pthread_mutex_lock(&GloVars.checksum_mutex);
// generate checksum for cluster
flush_ldap_variables___runtime_to_database(admindb, false, false, false, true);
char *error=NULL;
int cols=0;
int affected_rows=0;
SQLite3_result *resultset=NULL;
char *q=(char *)"SELECT variable_name, variable_value FROM runtime_global_variables WHERE variable_name LIKE 'ldap-\%' ORDER BY variable_name";
admindb->execute_statement(q, &error , &cols , &affected_rows , &resultset);
uint64_t hash1 = resultset->raw_checksum();
uint32_t d32[2];
char buf[20];
memcpy(&d32, &hash1, sizeof(hash1));
sprintf(buf,"0x%0X%0X", d32[0], d32[1]);
GloVars.checksums_values.ldap_variables.set_checksum(buf);
GloVars.checksums_values.ldap_variables.version++;
time_t t = time(NULL);
GloVars.checksums_values.ldap_variables.epoch = t;
GloVars.epoch_version = t;
GloVars.generate_global_checksum();
GloVars.checksums_values.updates_cnt++;
pthread_mutex_unlock(&GloVars.checksum_mutex);
delete resultset;
}
}
if (resultset) delete resultset;
}
@ -7099,6 +7132,10 @@ char * ProxySQL_Admin::get_variable(char *name) {
sprintf(intbuf,"%d",variables.cluster_admin_variables_diffs_before_sync);
return strdup(intbuf);
}
if (!strcasecmp(name,"cluster_ldap_variables_diffs_before_sync")) {
sprintf(intbuf,"%d",variables.cluster_ldap_variables_diffs_before_sync);
return strdup(intbuf);
}
if (!strcasecmp(name,"cluster_mysql_query_rules_save_to_disk")) {
return strdup((variables.cluster_mysql_query_rules_save_to_disk ? "true" : "false"));
}
@ -7117,6 +7154,9 @@ char * ProxySQL_Admin::get_variable(char *name) {
if (!strcasecmp(name,"cluster_admin_variables_save_to_disk")) {
return strdup((variables.cluster_admin_variables_save_to_disk ? "true" : "false"));
}
if (!strcasecmp(name,"cluster_ldap_variables_save_to_disk")) {
return strdup((variables.cluster_ldap_variables_save_to_disk ? "true" : "false"));
}
if (!strcasecmp(name,"refresh_interval")) {
sprintf(intbuf,"%d",variables.refresh_interval);
return strdup(intbuf);
@ -7145,6 +7185,9 @@ char * ProxySQL_Admin::get_variable(char *name) {
if (!strcasecmp(name,"checksum_admin_variables")) {
return strdup((checksum_variables.checksum_admin_variables ? "true" : "false"));
}
if (!strcasecmp(name,"checksum_ldap_variables")) {
return strdup((checksum_variables.checksum_ldap_variables ? "true" : "false"));
}
if (!strcasecmp(name,"restapi_enabled")) {
return strdup((variables.restapi_enabled ? "true" : "false"));
}
@ -7609,6 +7652,16 @@ bool ProxySQL_Admin::set_variable(char *name, char *value) { // this is the pub
return false;
}
}
if (!strcasecmp(name,"cluster_ldap_variables_diffs_before_sync")) {
int intv=atoi(value);
if (intv >= 0 && intv <= 1000) {
variables.cluster_ldap_variables_diffs_before_sync=intv;
__sync_lock_test_and_set(&GloProxyCluster->cluster_ldap_variables_diffs_before_sync, intv);
return true;
} else {
return false;
}
}
if (!strcasecmp(name,"version")) {
if (strcasecmp(value,(char *)PROXYSQL_VERSION)==0) {
return true;
@ -7775,6 +7828,20 @@ bool ProxySQL_Admin::set_variable(char *name, char *value) { // this is the pub
}
return rt;
}
if (!strcasecmp(name,"cluster_ldap_variables_save_to_disk")) {
bool rt = false;
if (strcasecmp(value,"true")==0 || strcasecmp(value,"1")==0) {
variables.cluster_ldap_variables_save_to_disk=true;
rt = __sync_lock_test_and_set(&GloProxyCluster->cluster_ldap_variables_save_to_disk, true);
return true;
}
if (strcasecmp(value,"false")==0 || strcasecmp(value,"0")==0) {
variables.cluster_ldap_variables_save_to_disk=false;
rt = __sync_lock_test_and_set(&GloProxyCluster->cluster_ldap_variables_save_to_disk, false);
return true;
}
return rt;
}
if (!strcasecmp(name,"checksum_mysql_query_rules")) {
if (strcasecmp(value,"true")==0 || strcasecmp(value,"1")==0) {
checksum_variables.checksum_mysql_query_rules=true;
@ -7830,6 +7897,17 @@ bool ProxySQL_Admin::set_variable(char *name, char *value) { // this is the pub
}
return false;
}
if (!strcasecmp(name,"checksum_ldap_variables")) {
if (strcasecmp(value,"true")==0 || strcasecmp(value,"1")==0) {
checksum_variables.checksum_ldap_variables=true;
return true;
}
if (strcasecmp(value,"false")==0 || strcasecmp(value,"0")==0) {
checksum_variables.checksum_ldap_variables=false;
return true;
}
return false;
}
if (!strcasecmp(name,"read_only")) {
if (strcasecmp(value,"true")==0 || strcasecmp(value,"1")==0) {
variables.admin_read_only=true;
@ -9774,6 +9852,14 @@ void ProxySQL_Admin::flush_admin_variables__from_memory_to_disk() {
admindb->wrunlock();
}
void ProxySQL_Admin::flush_ldap_variables__from_memory_to_disk() {
admindb->wrlock();
admindb->execute("PRAGMA foreign_keys = OFF");
admindb->execute("INSERT OR REPLACE INTO disk.global_variables SELECT * FROM main.global_variables WHERE variable_name LIKE 'ldap-%'");
admindb->execute("PRAGMA foreign_keys = ON");
admindb->wrunlock();
}
void ProxySQL_Admin::__attach_db(SQLite3DB *db1, SQLite3DB *db2, char *alias) {
const char *a="ATTACH DATABASE '%s' AS %s";
int l=strlen(a)+strlen(db2->get_url())+strlen(alias)+5;
@ -10271,6 +10357,16 @@ void ProxySQL_Admin::dump_checksums_values_table() {
rc=(*proxy_sqlite3_clear_bindings)(statement1); ASSERT_SQLITE_OK(rc, admindb);
rc=(*proxy_sqlite3_reset)(statement1); ASSERT_SQLITE_OK(rc, admindb);
if (GloMyLdapAuth) {
rc=(*proxy_sqlite3_bind_text)(statement1, 1, "ldap_variables", -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, admindb);
rc=(*proxy_sqlite3_bind_int64)(statement1, 2, GloVars.checksums_values.ldap_variables.version); ASSERT_SQLITE_OK(rc, admindb);
rc=(*proxy_sqlite3_bind_int64)(statement1, 3, GloVars.checksums_values.ldap_variables.epoch); ASSERT_SQLITE_OK(rc, admindb);
rc=(*proxy_sqlite3_bind_text)(statement1, 4, GloVars.checksums_values.ldap_variables.checksum, -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, admindb);
SAFE_SQLITE3_STEP2(statement1);
rc=(*proxy_sqlite3_clear_bindings)(statement1); ASSERT_SQLITE_OK(rc, admindb);
rc=(*proxy_sqlite3_reset)(statement1); ASSERT_SQLITE_OK(rc, admindb);
}
admindb->execute((char *)"COMMIT");
pthread_mutex_unlock(&GloVars.checksum_mutex);
(*proxy_sqlite3_finalize)(statement1);

@ -5,6 +5,7 @@
#include "prometheus_helpers.h"
#include "ProxySQL_Cluster.hpp"
#include "MySQL_LDAP_Authentication.hpp"
#ifdef DEBUG
#define DEB "_DEBUG"
@ -37,8 +38,8 @@
static char *NODE_COMPUTE_DELIMITER=(char *)"-gtyw23a-"; // a random string used for hashing
extern ProxySQL_Cluster * GloProxyCluster;
extern ProxySQL_Admin *GloAdmin;
extern MySQL_LDAP_Authentication* GloMyLdapAuth;
typedef struct _proxy_node_address_t {
pthread_t thrid;
@ -495,6 +496,26 @@ void ProxySQL_Node_Entry::set_checksums(MYSQL_RES *_r) {
}
continue;
}
if (GloMyLdapAuth && strcmp(row[0],"ldap_variables")==0) {
checksums_values.ldap_variables.version = atoll(row[1]);
checksums_values.ldap_variables.epoch = atoll(row[2]);
checksums_values.ldap_variables.last_updated = now;
if (strcmp(checksums_values.ldap_variables.checksum, row[3])) {
strcpy(checksums_values.ldap_variables.checksum, row[3]);
checksums_values.ldap_variables.last_changed = now;
checksums_values.ldap_variables.diff_check = 1;
proxy_info("Cluster: detected a new checksum for ldap_variables from peer %s:%d, version %llu, epoch %llu, checksum %s . Not syncing yet ...\n", hostname, port, checksums_values.ldap_variables.version, checksums_values.ldap_variables.epoch, checksums_values.ldap_variables.checksum);
if (strcmp(checksums_values.ldap_variables.checksum, GloVars.checksums_values.ldap_variables.checksum) == 0) {
proxy_info("Cluster: checksum for ldap_variables from peer %s:%d matches with local checksum %s , we won't sync.\n", hostname, port, GloVars.checksums_values.ldap_variables.checksum);
}
} else {
checksums_values.ldap_variables.diff_check++;
}
if (strcmp(checksums_values.ldap_variables.checksum, GloVars.checksums_values.ldap_variables.checksum) == 0) {
checksums_values.ldap_variables.diff_check = 0;
}
continue;
}
}
if (_r == NULL) {
ProxySQL_Checksum_Value_2 *v = NULL;
@ -540,6 +561,13 @@ void ProxySQL_Node_Entry::set_checksums(MYSQL_RES *_r) {
}
if (v->diff_check)
v->diff_check++;
v = &checksums_values.ldap_variables;
v->last_updated = now;
if (strcmp(v->checksum, GloVars.checksums_values.ldap_variables.checksum) == 0) {
v->diff_check = 0;
}
if (v->diff_check)
v->diff_check++;
}
pthread_mutex_unlock(&GloVars.checksum_mutex);
// we now do a series of checks, and we take action
@ -550,6 +578,7 @@ void ProxySQL_Node_Entry::set_checksums(MYSQL_RES *_r) {
unsigned int diff_mu = (unsigned int)__sync_fetch_and_add(&GloProxyCluster->cluster_mysql_users_diffs_before_sync,0);
unsigned int diff_ps = (unsigned int)__sync_fetch_and_add(&GloProxyCluster->cluster_proxysql_servers_diffs_before_sync,0);
unsigned int diff_mv = (unsigned int)__sync_fetch_and_add(&GloProxyCluster->cluster_mysql_variables_diffs_before_sync,0);
unsigned int diff_lv = (unsigned int)__sync_fetch_and_add(&GloProxyCluster->cluster_ldap_variables_diffs_before_sync,0);
unsigned int diff_av = (unsigned int)__sync_fetch_and_add(&GloProxyCluster->cluster_admin_variables_diffs_before_sync,0);
ProxySQL_Checksum_Value_2 *v = NULL;
if (diff_mqr) {
@ -716,6 +745,34 @@ void ProxySQL_Node_Entry::set_checksums(MYSQL_RES *_r) {
}
}
}
if (GloMyLdapAuth && diff_lv) {
v = &checksums_values.ldap_variables;
unsigned long long own_version = __sync_fetch_and_add(&GloVars.checksums_values.ldap_variables.version, 0);
unsigned long long own_epoch = __sync_fetch_and_add(&GloVars.checksums_values.ldap_variables.epoch, 0);
char* own_checksum = __sync_fetch_and_add(&GloVars.checksums_values.ldap_variables.checksum, 0);
if (v->version > 1) {
if (
(own_version == 1) // we just booted
||
(v->epoch > own_epoch) // epoch is newer
) {
if (v->diff_check >= diff_lv) {
proxy_info("Cluster: detected a peer %s:%d with ldap_variables version %llu, epoch %llu, diff_check %u. Own version: %llu, epoch: %llu. Proceeding with remote sync\n", hostname, port, v->version, v->epoch, v->diff_check, own_version, own_epoch);
GloProxyCluster->pull_global_variables_from_peer("ldap");
}
}
if ((v->epoch == own_epoch) && v->diff_check && ((v->diff_check % (diff_lv*10)) == 0)) {
proxy_error("Cluster: detected a peer %s:%d with ldap_variables version %llu, epoch %llu, diff_check %u, checksum %s. Own version: %llu, epoch: %llu, checksum %s. Sync conflict, epoch times are EQUAL, can't determine which server holds the latest config, we won't sync. This message will be repeated every %llu checks until LOAD LDAP VARIABLES is executed on candidate master.\n", hostname, port, v->version, v->epoch, v->diff_check, v->checksum, own_version, own_epoch, own_checksum, (diff_lv*10));
GloProxyCluster->metrics.p_counter_array[p_cluster_counter::sync_conflict_ldap_variables_share_epoch]->Increment();
}
} else {
if (v->diff_check && (v->diff_check % (diff_lv*10)) == 0) {
proxy_warning("Cluster: detected a peer %s:%d with ldap_variables version %llu, epoch %llu, diff_check %u. Own version: %llu, epoch: %llu. diff_check is increasing, but version 1 doesn't allow sync. This message will be repeated every %llu checks until LOAD LDAP VARIABLES TO RUNTIME is executed on candidate master.\n", hostname, port, v->version, v->epoch, v->diff_check, own_version, own_epoch, (diff_lv*10));
GloProxyCluster->metrics.p_counter_array[p_cluster_counter::sync_delayed_ldap_variables_version_one]->Increment();
}
}
}
}
void ProxySQL_Cluster::pull_mysql_query_rules_from_peer() {
@ -944,7 +1001,7 @@ void ProxySQL_Cluster::pull_mysql_users_from_peer() {
proxy_info("Cluster: Fetching MySQL Users from peer %s:%d completed\n", hostname, port);
proxy_info("Cluster: Loading to runtime MySQL Users from peer %s:%d\n", hostname, port);
GloAdmin->init_users();
if (GloProxyCluster->cluster_mysql_query_rules_save_to_disk == true) {
if (GloProxyCluster->cluster_mysql_users_save_to_disk == true) {
proxy_info("Cluster: Saving to disk MySQL Users from peer %s:%d\n", hostname, port);
GloAdmin->flush_mysql_users__from_memory_to_disk();
} else {
@ -955,9 +1012,57 @@ void ProxySQL_Cluster::pull_mysql_users_from_peer() {
proxy_info("Cluster: Fetching MySQL Users from peer %s:%d failed: %s\n", hostname, port, mysql_error(conn));
metrics.p_counter_array[p_cluster_counter::pulled_mysql_users_failure]->Increment();
}
if (GloMyLdapAuth) {
rc_query = mysql_query(
conn,
"SELECT priority, frontend_entity, backend_entity, comment FROM runtime_mysql_ldap_mapping"
);
if (rc_query == 0) {
MYSQL_RES *result = mysql_store_result(conn);
GloAdmin->admindb->execute("DELETE FROM mysql_ldap_mapping");
MYSQL_ROW row;
char* q = const_cast<char*>(
"INSERT INTO mysql_ldap_mapping (priority, frontend_entity, backend_entity, comment)"
" VALUES (?1 , ?2 , ?3 , ?4)"
);
sqlite3_stmt *statement1 = NULL;
rc = GloAdmin->admindb->prepare_v2(q, &statement1);
ASSERT_SQLITE_OK(rc, GloAdmin->admindb);
while ((row = mysql_fetch_row(result))) {
rc=(*proxy_sqlite3_bind_int64)(statement1, 1, atoll(row[0])); ASSERT_SQLITE_OK(rc, GloAdmin->admindb); // priority
rc=(*proxy_sqlite3_bind_text)(statement1, 2, row[1], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, GloAdmin->admindb); // frontend_entity
rc=(*proxy_sqlite3_bind_text)(statement1, 3, row[2], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, GloAdmin->admindb); // backend_entity
rc=(*proxy_sqlite3_bind_text)(statement1, 4, row[3], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, GloAdmin->admindb); // comment
SAFE_SQLITE3_STEP2(statement1);
rc=(*proxy_sqlite3_clear_bindings)(statement1); ASSERT_SQLITE_OK(rc, GloAdmin->admindb);
rc=(*proxy_sqlite3_reset)(statement1); ASSERT_SQLITE_OK(rc, GloAdmin->admindb);
}
mysql_free_result(result);
proxy_info("Cluster: Fetching LDAP Mappings from peer %s:%d completed\n", hostname, port);
proxy_info("Cluster: Loading to runtime LDAP Mappings from peer %s:%d\n", hostname, port);
GloAdmin->init_users();
if (GloProxyCluster->cluster_mysql_users_save_to_disk == true) {
proxy_info("Cluster: Saving to disk LDAP Mappings from peer %s:%d\n", hostname, port);
GloAdmin->flush_mysql_users__from_memory_to_disk();
} else {
proxy_info("Cluster: Saving to disk LDAP Mappings Rules from peer %s:%d\n", hostname, port);
}
metrics.p_counter_array[p_cluster_counter::pulled_mysql_ldap_mapping_success]->Increment();
} else {
proxy_info("Cluster: Fetching LDAP Mappings from peer %s:%d failed: %s\n", hostname, port, mysql_error(conn));
metrics.p_counter_array[p_cluster_counter::pulled_mysql_ldap_mapping_failure]->Increment();
}
}
} else {
proxy_info("Cluster: Fetching MySQL Users from peer %s:%d failed: %s\n", hostname, port, mysql_error(conn));
metrics.p_counter_array[p_cluster_counter::pulled_mysql_users_failure]->Increment();
metrics.p_counter_array[p_cluster_counter::pulled_mysql_ldap_mapping_failure]->Increment();
}
}
__exit_pull_mysql_users_from_peer:
@ -1377,16 +1482,25 @@ void ProxySQL_Cluster::pull_global_variables_from_peer(const std::string& var_ty
vars_type_str = const_cast<char*>("Admin");
success_metric = p_cluster_counter::pulled_admin_variables_success;
failure_metric = p_cluster_counter::pulled_admin_variables_failure;
} else if (var_type == "ldap") {
vars_type_str = const_cast<char*>("LDAP");
success_metric = p_cluster_counter::pulled_ldap_variables_success;
failure_metric = p_cluster_counter::pulled_ldap_variables_failure;
} else {
proxy_error("Invalid parameter supplied to 'pull_global_variables_from_peer': var_type=%s", var_type.c_str());
proxy_error("Invalid parameter supplied to 'pull_global_variables_from_peer': var_type=%s\n", var_type.c_str());
assert(0);
}
pthread_mutex_lock(&GloProxyCluster->update_mysql_variables_mutex);
if (var_type == "mysql") {
nodes.get_peer_to_sync_mysql_variables(&hostname, &port);
} else {
} else if (var_type == "admin") {
nodes.get_peer_to_sync_admin_variables(&hostname, &port);
} else if (var_type == "ldap"){
nodes.get_peer_to_sync_ldap_variables(&hostname, &port);
} else {
proxy_error("Invalid parameter supplied to 'pull_global_variables_from_peer': var_type=%s\n", var_type.c_str());
assert(0);
}
if (hostname) {
@ -1450,13 +1564,23 @@ void ProxySQL_Cluster::pull_global_variables_from_peer(const std::string& var_ty
proxy_info("Cluster: Saving to disk MySQL Variables from peer %s:%d\n", hostname, port);
GloAdmin->flush_mysql_variables__from_memory_to_disk();
}
} else {
} else if (var_type == "admin") {
GloAdmin->load_admin_variables_to_runtime();
if (GloProxyCluster->cluster_admin_variables_save_to_disk == true) {
proxy_info("Cluster: Saving to disk Admin Variables from peer %s:%d\n", hostname, port);
GloAdmin->flush_admin_variables__from_memory_to_disk();
}
} else if (var_type == "ldap") {
GloAdmin->load_ldap_variables_to_runtime();
if (GloProxyCluster->cluster_ldap_variables_save_to_disk == true) {
proxy_info("Cluster: Saving to disk LDAP Variables from peer %s:%d\n", hostname, port);
GloAdmin->flush_ldap_variables__from_memory_to_disk();
}
} else {
proxy_error("Invalid parameter supplied to 'pull_global_variables_from_peer': var_type=%s\n", var_type.c_str());
assert(0);
}
metrics.p_counter_array[success_metric]->Increment();
} else {
@ -1973,6 +2097,48 @@ void ProxySQL_Cluster_Nodes::get_peer_to_sync_admin_variables(char **host, uint1
}
}
void ProxySQL_Cluster_Nodes::get_peer_to_sync_ldap_variables(char **host, uint16_t *port) {
unsigned long long version = 0;
unsigned long long epoch = 0;
unsigned long long max_epoch = 0;
char *hostname = NULL;
uint16_t p = 0;
unsigned int diff_mu = (unsigned int)__sync_fetch_and_add(&GloProxyCluster->cluster_ldap_variables_diffs_before_sync,0);
for (std::unordered_map<uint64_t, ProxySQL_Node_Entry *>::iterator it = umap_proxy_nodes.begin(); it != umap_proxy_nodes.end();) {
ProxySQL_Node_Entry * node = it->second;
ProxySQL_Checksum_Value_2 * v = &node->checksums_values.ldap_variables;
if (v->version > 1) {
if ( v->epoch > epoch ) {
max_epoch = v->epoch;
if (v->diff_check > diff_mu) {
epoch = v->epoch;
version = v->version;
if (hostname) {
free(hostname);
}
hostname=strdup(node->get_hostname());
p = node->get_port();
}
}
}
it++;
}
if (epoch) {
if (max_epoch > epoch) {
proxy_warning("Cluster: detected a peer with ldap_variables epoch %llu, but not enough diff_check. We won't sync from epoch %llu: temporarily skipping sync\n", max_epoch, epoch);
if (hostname) {
free(hostname);
hostname = NULL;
}
}
}
if (hostname) {
*host = hostname;
*port = p;
proxy_info("Cluster: detected peer %s:%d with ldap_variables version %llu, epoch %llu\n", hostname, p, version, epoch);
}
}
void ProxySQL_Cluster_Nodes::get_peer_to_sync_proxysql_servers(char **host, uint16_t *port) {
unsigned long long version = 0;
unsigned long long epoch = 0;
@ -2454,6 +2620,46 @@ cluster_metrics_map = std::make_tuple(
}
),
// ldap_variables_*
std::make_tuple (
p_cluster_counter::pulled_ldap_variables_success,
"proxysql_cluster_pulled_total",
"Number of times a 'module' have been pulled from a peer.",
metric_tags {
{ "module_name", "ldap_variables" },
{ "status", "success" }
}
),
std::make_tuple (
p_cluster_counter::pulled_ldap_variables_failure,
"proxysql_cluster_pulled_total",
"Number of times a 'module' have been pulled from a peer.",
metric_tags {
{ "module_name", "ldap_variables" },
{ "status", "failure" }
}
),
// mysql_ldap_mappings_*
std::make_tuple (
p_cluster_counter::pulled_mysql_ldap_mapping_success,
"proxysql_cluster_pulled_total",
"Number of times a 'module' have been pulled from a peer.",
metric_tags {
{ "module_name", "mysql_ldap_mapping" },
{ "status", "success" }
}
),
std::make_tuple (
p_cluster_counter::pulled_mysql_ldap_mapping_failure,
"proxysql_cluster_pulled_total",
"Number of times a 'module' have been pulled from a peer.",
metric_tags {
{ "module_name", "mysql_ldap_mapping" },
{ "status", "failure" }
}
),
// sync_conflict same epoch
// ====================================================================
std::make_tuple (
@ -2510,6 +2716,15 @@ cluster_metrics_map = std::make_tuple(
{ "reason", "servers_share_epoch" }
}
),
std::make_tuple (
p_cluster_counter::sync_conflict_ldap_variables_share_epoch,
"proxysql_cluster_syn_conflict_total",
"Number of times a 'module' has not been able to be synced.",
metric_tags {
{ "module_name", "ldap_variables" },
{ "reason", "servers_share_epoch" }
}
),
// ====================================================================
// sync_delayed due to version one
@ -2567,7 +2782,16 @@ cluster_metrics_map = std::make_tuple(
{ "module_name", "admin_variables" },
{ "reason", "version_one" }
}
)
),
std::make_tuple (
p_cluster_counter::sync_delayed_ldap_variables_version_one,
"proxysql_cluster_syn_conflict_total",
"Number of times a 'module' has not been able to be synced.",
metric_tags {
{ "module_name", "ldap_variables" },
{ "reason", "version_one" }
}
),
// ====================================================================
},
cluster_gauge_vector {}

@ -7,6 +7,10 @@
#include "SpookyV2.h"
#include <cxxabi.h>
#include "MySQL_LDAP_Authentication.hpp"
extern MySQL_LDAP_Authentication* GloMyLdapAuth;
static void term_handler(int sig) {
proxy_warning("Received TERM signal: shutdown in progress...\n");
#ifdef DEBUG
@ -367,6 +371,13 @@ uint64_t ProxySQL_GlobalVariables::generate_global_checksum() {
myhash.Update(v->checksum,strlen(v->checksum));
myhash.Update(&v->version,sizeof(v->version));
}
if (GloMyLdapAuth) {
v = &checksums_values.ldap_variables;
if (v->version) {
myhash.Update(v->checksum,strlen(v->checksum));
myhash.Update(&v->version,sizeof(v->version));
}
}
uint64_t h1, h2;
myhash.Final(&h1, &h2);
h1 = h1/2; // ugly way to make it signed within LLONG_MAX

@ -6,9 +6,12 @@
#include <cstring>
#include <memory>
#include <openssl/ssl.h>
#include "proxysql_structs.h"
#include "proxysql_glovars.hpp"
#include "sqlite3db.h"
#include "MySQL_LDAP_Authentication.hpp"
MySQL_LDAP_Authentication* GloMyLdapAuth = nullptr;
int main() {
SQLite3DB::LoadPlugin(NULL);

Loading…
Cancel
Save