@ -9,10 +9,25 @@
# endif /* DEBUG */
# define PROXYSQL_CLUSTER_VERSION "0.1.0702" DEB
# define SAFE_SQLITE3_STEP(_stmt) do {\
do { \
rc = sqlite3_step ( _stmt ) ; \
if ( rc ! = SQLITE_DONE ) { \
assert ( rc = = SQLITE_LOCKED ) ; \
usleep ( 10 ) ; \
} \
} while ( rc ! = SQLITE_DONE ) ; \
} while ( 0 )
static char * NODE_COMPUTE_DELIMITER = ( char * ) " -gtyw23a- " ; // a random string used for hashing
extern ProxySQL_Cluster * GloProxyCluster ;
extern ProxySQL_Admin * GloAdmin ;
typedef struct _proxy_node_address_t {
pthread_t thrid ;
uint64_t hash ; // unused for now
@ -35,6 +50,7 @@ void * ProxySQL_Cluster_Monitor_thread(void *args) {
mysql_thread_init ( ) ;
pthread_detach ( pthread_self ( ) ) ;
proxy_info ( " Cluster: starting thread for peer %s:%d \n " , node - > hostname , node - > port ) ;
char * query1 = ( char * ) " SELECT GLOBAL_CHECKSUM() " ; // in future this will be used for "light check"
char * query2 = ( char * ) " SELECT * FROM stats_mysql_global ORDER BY Variable_Name " ;
char * query3 = ( char * ) " SELECT * FROM runtime_checksums_values ORDER BY name " ;
@ -153,6 +169,7 @@ void * ProxySQL_Cluster_Monitor_thread(void *args) {
mysql_close ( conn ) ;
}
} else {
proxy_warning ( " Cluster: unable to connect to peer %s:%d . Error: %s \n " , node - > hostname , node - > port , mysql_error ( conn ) ) ;
mysql_close ( conn ) ;
conn = mysql_init ( NULL ) ;
int ci = __sync_fetch_and_add ( & GloProxyCluster - > cluster_check_interval_ms , 0 ) ;
@ -167,6 +184,7 @@ __exit_monitor_thread:
if ( conn - > net . vio ) {
mysql_close ( conn ) ;
}
proxy_info ( " Cluster: closing thread for peer %s:%d \n " , node - > hostname , node - > port ) ;
free ( node - > hostname ) ;
free ( node ) ;
//pthread_exit(0);
@ -217,9 +235,11 @@ ProxySQL_Node_Entry::ProxySQL_Node_Entry(char *_hostname, uint16_t _port, uint64
for ( int i = 0 ; i < PROXYSQL_NODE_METRICS_LEN ; i + + ) {
metrics [ i ] = new ProxySQL_Node_Metrics ( ) ;
}
proxy_info ( " Created new Cluster Node Entry for host %s:%d \n " , hostname , port ) ;
}
ProxySQL_Node_Entry : : ~ ProxySQL_Node_Entry ( ) {
proxy_info ( " Destroyed Cluster Node Entry for host %s:%d \n " , hostname , port ) ;
if ( hostname ) {
free ( hostname ) ;
hostname = NULL ;
@ -302,6 +322,10 @@ void ProxySQL_Node_Entry::set_checksums(MYSQL_RES *_r) {
strcpy ( checksums_values . mysql_query_rules . checksum , row [ 3 ] ) ;
checksums_values . mysql_query_rules . last_changed = now ;
checksums_values . mysql_query_rules . diff_check = 1 ;
proxy_info ( " Cluster: detected a new checksum for mysql_query_rules from peer %s:%d, version %llu, epoch %llu, checksum %s . Not syncing yet ... \n " , hostname , port , checksums_values . mysql_query_rules . version , checksums_values . mysql_query_rules . epoch , checksums_values . mysql_query_rules . checksum ) ;
if ( strcmp ( checksums_values . mysql_query_rules . checksum , GloVars . checksums_values . mysql_query_rules . checksum ) = = 0 ) {
proxy_info ( " Cluster: checksum for mysql_query_rules from peer %s:%d matches with local checksum %s , we won't sync. \n " , hostname , port , GloVars . checksums_values . mysql_query_rules . checksum ) ;
}
} else {
checksums_values . mysql_query_rules . diff_check + + ;
}
@ -318,6 +342,10 @@ void ProxySQL_Node_Entry::set_checksums(MYSQL_RES *_r) {
strcpy ( checksums_values . mysql_servers . checksum , row [ 3 ] ) ;
checksums_values . mysql_servers . last_changed = now ;
checksums_values . mysql_servers . diff_check = 1 ;
proxy_info ( " Cluster: detected a new checksum for mysql_servers from peer %s:%d, version %llu, epoch %llu, checksum %s . Not syncing yet ... \n " , hostname , port , checksums_values . mysql_servers . version , checksums_values . mysql_servers . epoch , checksums_values . mysql_servers . checksum ) ;
if ( strcmp ( checksums_values . mysql_servers . checksum , GloVars . checksums_values . mysql_servers . checksum ) = = 0 ) {
proxy_info ( " Cluster: checksum for mysql_servers from peer %s:%d matches with local checksum %s , we won't sync. \n " , hostname , port , GloVars . checksums_values . mysql_servers . checksum ) ;
}
} else {
checksums_values . mysql_servers . diff_check + + ;
}
@ -334,6 +362,10 @@ void ProxySQL_Node_Entry::set_checksums(MYSQL_RES *_r) {
strcpy ( checksums_values . mysql_users . checksum , row [ 3 ] ) ;
checksums_values . mysql_users . last_changed = now ;
checksums_values . mysql_users . diff_check = 1 ;
proxy_info ( " Cluster: detected a new checksum for mysql_users from peer %s:%d, version %llu, epoch %llu, checksum %s . Not syncing yet ... \n " , hostname , port , checksums_values . mysql_users . version , checksums_values . mysql_users . epoch , checksums_values . mysql_users . checksum ) ;
if ( strcmp ( checksums_values . mysql_users . checksum , GloVars . checksums_values . mysql_users . checksum ) = = 0 ) {
proxy_info ( " Cluster: checksum for mysql_users from peer %s:%d matches with local checksum %s , we won't sync. \n " , hostname , port , GloVars . checksums_values . mysql_users . checksum ) ;
}
} else {
checksums_values . mysql_users . diff_check + + ;
}
@ -366,6 +398,10 @@ void ProxySQL_Node_Entry::set_checksums(MYSQL_RES *_r) {
strcpy ( checksums_values . proxysql_servers . checksum , row [ 3 ] ) ;
checksums_values . proxysql_servers . last_changed = now ;
checksums_values . proxysql_servers . diff_check = 1 ;
proxy_info ( " Cluster: detected a new checksum for proxysql_servers from peer %s:%d, version %llu, epoch %llu, checksum %s . Not syncing yet ... \n " , hostname , port , checksums_values . proxysql_servers . version , checksums_values . proxysql_servers . epoch , checksums_values . proxysql_servers . checksum ) ;
if ( strcmp ( checksums_values . proxysql_servers . checksum , GloVars . checksums_values . proxysql_servers . checksum ) = = 0 ) {
proxy_info ( " Cluster: checksum for proxysql_servers from peer %s:%d matches with local checksum %s , we won't sync. \n " , hostname , port , GloVars . checksums_values . proxysql_servers . checksum ) ;
}
} else {
checksums_values . proxysql_servers . diff_check + + ;
}
@ -383,14 +419,23 @@ void ProxySQL_Node_Entry::set_checksums(MYSQL_RES *_r) {
v - > diff_check + + ;
v = & checksums_values . mysql_query_rules ;
v - > last_updated = now ;
if ( strcmp ( v - > checksum , GloVars . checksums_values . mysql_query_rules . checksum ) = = 0 ) {
v - > diff_check = 0 ;
}
if ( v - > diff_check )
v - > diff_check + + ;
v = & checksums_values . mysql_servers ;
v - > last_updated = now ;
if ( strcmp ( v - > checksum , GloVars . checksums_values . mysql_servers . checksum ) = = 0 ) {
v - > diff_check = 0 ;
}
if ( v - > diff_check )
v - > diff_check + + ;
v = & checksums_values . mysql_users ;
v - > last_updated = now ;
if ( strcmp ( v - > checksum , GloVars . checksums_values . mysql_users . checksum ) = = 0 ) {
v - > diff_check = 0 ;
}
if ( v - > diff_check )
v - > diff_check + + ;
v = & checksums_values . mysql_variables ;
@ -399,10 +444,460 @@ void ProxySQL_Node_Entry::set_checksums(MYSQL_RES *_r) {
v - > diff_check + + ;
v = & checksums_values . proxysql_servers ;
v - > last_updated = now ;
if ( strcmp ( v - > checksum , GloVars . checksums_values . proxysql_servers . 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
// note that this is done outside the critical section
// as mutex on GloVars.checksum_mutex is already released
unsigned int diff_mqr = ( unsigned int ) __sync_fetch_and_add ( & GloProxyCluster - > cluster_mysql_query_rules_diffs_before_sync , 0 ) ;
unsigned int diff_ms = ( unsigned int ) __sync_fetch_and_add ( & GloProxyCluster - > cluster_mysql_servers_diffs_before_sync , 0 ) ;
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 ) ;
ProxySQL_Checksum_Value_2 * v = NULL ;
if ( diff_mqr ) {
unsigned long long own_version = __sync_fetch_and_add ( & GloVars . checksums_values . mysql_query_rules . version , 0 ) ;
unsigned long long own_epoch = __sync_fetch_and_add ( & GloVars . checksums_values . mysql_query_rules . epoch , 0 ) ;
v = & checksums_values . mysql_query_rules ;
if ( v - > version > 1 ) {
if (
( own_version = = 1 ) // we just booted
| |
( v - > epoch > own_version ) // epoch is newer
) {
if ( v - > diff_check > diff_mqr ) {
proxy_info ( " Cluster: detected a peer %s:%d with mysql_query_rules version %llu, epoch %llu, diff_check %llu. 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_mysql_query_rules_from_peer ( ) ;
}
}
} else {
if ( v - > diff_check & & ( v - > diff_check % ( diff_mqr * 10 ) ) = = 0 ) {
proxy_warning ( " Cluster: detected a peer %s:%d with mysql_query_rules version %llu, epoch %llu, diff_check %llu. 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 MYSQL QUERY RULES TO RUNTIME is executed on candidate master. \n " , hostname , port , v - > version , v - > epoch , v - > diff_check , own_version , own_epoch , ( diff_mqr * 10 ) ) ;
}
}
}
if ( diff_ms ) {
v = & checksums_values . mysql_servers ;
unsigned long long own_version = __sync_fetch_and_add ( & GloVars . checksums_values . mysql_servers . version , 0 ) ;
unsigned long long own_epoch = __sync_fetch_and_add ( & GloVars . checksums_values . mysql_servers . epoch , 0 ) ;
if ( v - > version > 1 ) {
if (
( own_version = = 1 ) // we just booted
| |
( v - > epoch > own_version ) // epoch is newer
) {
if ( v - > diff_check > diff_ms ) {
proxy_info ( " Cluster: detected a peer %s:%d with mysql_servers version %llu, epoch %llu, diff_check %llu. 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_mysql_servers_from_peer ( ) ;
}
}
} else {
if ( v - > diff_check & & ( v - > diff_check % ( diff_ms * 10 ) ) = = 0 ) {
proxy_warning ( " Cluster: detected a peer %s:%d with mysql_servers version %llu, epoch %llu, diff_check %llu. 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 MYSQL SERVERS TO RUNTIME is executed on candidate master. \n " , hostname , port , v - > version , v - > epoch , v - > diff_check , own_version , own_epoch , ( diff_ms * 10 ) ) ;
}
}
}
if ( diff_mu ) {
v = & checksums_values . mysql_users ;
unsigned long long own_version = __sync_fetch_and_add ( & GloVars . checksums_values . mysql_users . version , 0 ) ;
unsigned long long own_epoch = __sync_fetch_and_add ( & GloVars . checksums_values . mysql_users . epoch , 0 ) ;
if ( v - > version > 1 ) {
if (
( own_version = = 1 ) // we just booted
| |
( v - > epoch > own_version ) // epoch is newer
) {
if ( v - > diff_check > diff_mu ) {
proxy_info ( " Cluster: detected a peer %s:%d with mysql_users version %llu, epoch %llu, diff_check %llu. 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_mysql_users_from_peer ( ) ;
}
}
} else {
if ( v - > diff_check & & ( v - > diff_check % ( diff_mu * 10 ) ) = = 0 ) {
proxy_warning ( " Cluster: detected a peer %s:%d with mysql_users version %llu, epoch %llu, diff_check %llu. 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 MYSQL SERVERS TO RUNTIME is executed on candidate master. \n " , hostname , port , v - > version , v - > epoch , v - > diff_check , own_version , own_epoch , ( diff_mu * 10 ) ) ;
}
}
}
if ( diff_ps ) {
v = & checksums_values . proxysql_servers ;
unsigned long long own_version = __sync_fetch_and_add ( & GloVars . checksums_values . proxysql_servers . version , 0 ) ;
unsigned long long own_epoch = __sync_fetch_and_add ( & GloVars . checksums_values . proxysql_servers . epoch , 0 ) ;
if ( v - > version > 1 ) {
if (
( own_version = = 1 ) // we just booted
| |
( v - > epoch > own_version ) // epoch is newer
) {
if ( v - > diff_check > diff_ps ) {
proxy_info ( " Cluster: detected a peer %s:%d with proxysql_servers version %llu, epoch %llu, diff_check %llu. 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_proxysql_servers_from_peer ( ) ;
}
}
} else {
if ( v - > diff_check & & ( v - > diff_check % ( diff_ms * 10 ) ) = = 0 ) {
proxy_warning ( " Cluster: detected a peer %s:%d with proxysql_servers version %llu, epoch %llu, diff_check %llu. 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 PROXYSQL SERVERS TO RUNTIME is executed on candidate master. \n " , hostname , port , v - > version , v - > epoch , v - > diff_check , own_version , own_epoch , ( diff_ps * 10 ) ) ;
}
}
}
}
void ProxySQL_Cluster : : pull_mysql_query_rules_from_peer ( ) {
char * hostname = NULL ;
uint16_t port = 0 ;
pthread_mutex_lock ( & GloProxyCluster - > update_mysql_query_rules_mutex ) ;
nodes . get_peer_to_sync_mysql_query_rules ( & hostname , & port ) ;
if ( hostname ) {
char * username = NULL ;
char * password = NULL ;
bool rc_bool = true ;
MYSQL * rc_conn ;
int rc_query ;
int rc ;
MYSQL * conn = mysql_init ( NULL ) ;
if ( conn = = NULL ) {
proxy_error ( " Unable to run mysql_init() \n " ) ;
goto __exit_pull_mysql_query_rules_from_peer ;
}
GloProxyCluster - > get_credentials ( & username , & password ) ;
if ( strlen ( username ) ) { // do not monitor if the username is empty
unsigned int timeout = 1 ;
unsigned int timeout_long = 60 ;
mysql_options ( conn , MYSQL_OPT_CONNECT_TIMEOUT , & timeout ) ;
mysql_options ( conn , MYSQL_OPT_READ_TIMEOUT , & timeout_long ) ;
mysql_options ( conn , MYSQL_OPT_WRITE_TIMEOUT , & timeout ) ;
proxy_info ( " Cluster: Fetching MySQL Query Rules from peer %s:%d started \n " , hostname , port ) ;
rc_conn = mysql_real_connect ( conn , hostname , username , password , NULL , port , NULL , 0 ) ;
if ( rc_conn ) {
rc_query = mysql_query ( conn , " SELECT rule_id, username, schemaname, flagIN, client_addr, proxy_addr, proxy_port, digest, match_digest, match_pattern, negate_match_pattern, re_modifiers, flagOUT, replace_pattern, destination_hostgroup, cache_ttl, reconnect, timeout, retries, delay, next_query_flagIN, mirror_flagOUT, mirror_hostgroup, error_msg, ok_msg, sticky_conn, multiplex, log, apply, comment FROM runtime_mysql_query_rules " ) ;
if ( rc_query = = 0 ) {
MYSQL_RES * result = mysql_store_result ( conn ) ;
GloAdmin - > admindb - > execute ( " DELETE FROM mysql_query_rules " ) ;
MYSQL_ROW row ;
char * q = ( char * ) " INSERT INTO mysql_query_rules (rule_id, username, schemaname, flagIN, client_addr, proxy_addr, proxy_port, digest, match_digest, match_pattern, negate_match_pattern, re_modifiers, flagOUT, replace_pattern, destination_hostgroup, cache_ttl, reconnect, timeout, retries, delay, next_query_flagIN, mirror_flagOUT, mirror_hostgroup, error_msg, ok_msg, sticky_conn, multiplex, log, apply, comment) VALUES (?1 , ?2 , ?3 , ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30) " ;
sqlite3_stmt * statement1 = NULL ;
sqlite3 * mydb3 = GloAdmin - > admindb - > get_db ( ) ;
rc = sqlite3_prepare_v2 ( mydb3 , q , - 1 , & statement1 , 0 ) ;
assert ( rc = = SQLITE_OK ) ;
while ( ( row = mysql_fetch_row ( result ) ) ) {
rc = sqlite3_bind_int64 ( statement1 , 1 , atoll ( row [ 0 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // rule_id
rc = sqlite3_bind_text ( statement1 , 2 , row [ 1 ] , - 1 , SQLITE_TRANSIENT ) ; assert ( rc = = SQLITE_OK ) ; // username
rc = sqlite3_bind_text ( statement1 , 3 , row [ 2 ] , - 1 , SQLITE_TRANSIENT ) ; assert ( rc = = SQLITE_OK ) ; // schemaname
rc = sqlite3_bind_int64 ( statement1 , 4 , atoll ( row [ 3 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // flagIN
rc = sqlite3_bind_text ( statement1 , 5 , row [ 4 ] , - 1 , SQLITE_TRANSIENT ) ; assert ( rc = = SQLITE_OK ) ; // client_addr
rc = sqlite3_bind_text ( statement1 , 6 , row [ 5 ] , - 1 , SQLITE_TRANSIENT ) ; assert ( rc = = SQLITE_OK ) ; // proxy_addr
rc = sqlite3_bind_int64 ( statement1 , 7 , atoll ( row [ 6 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // proxy_port
rc = sqlite3_bind_text ( statement1 , 8 , row [ 7 ] , - 1 , SQLITE_TRANSIENT ) ; assert ( rc = = SQLITE_OK ) ; // digest
rc = sqlite3_bind_text ( statement1 , 9 , row [ 8 ] , - 1 , SQLITE_TRANSIENT ) ; assert ( rc = = SQLITE_OK ) ; // match_digest
rc = sqlite3_bind_text ( statement1 , 10 , row [ 9 ] , - 1 , SQLITE_TRANSIENT ) ; assert ( rc = = SQLITE_OK ) ; // match_pattern
rc = sqlite3_bind_int64 ( statement1 , 11 , atoll ( row [ 10 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // negate_match_pattern
rc = sqlite3_bind_text ( statement1 , 12 , row [ 11 ] , - 1 , SQLITE_TRANSIENT ) ; assert ( rc = = SQLITE_OK ) ; // re_modifiers
rc = sqlite3_bind_int64 ( statement1 , 13 , atoll ( row [ 12 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // flagOUT
rc = sqlite3_bind_text ( statement1 , 14 , row [ 13 ] , - 1 , SQLITE_TRANSIENT ) ; assert ( rc = = SQLITE_OK ) ; // replace_pattern
rc = sqlite3_bind_int64 ( statement1 , 15 , atoll ( row [ 14 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // destination_hostgroup
rc = sqlite3_bind_int64 ( statement1 , 16 , atoll ( row [ 15 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // cache_ttl
rc = sqlite3_bind_int64 ( statement1 , 17 , atoll ( row [ 16 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // reconnect
rc = sqlite3_bind_int64 ( statement1 , 18 , atoll ( row [ 17 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // timeout
rc = sqlite3_bind_int64 ( statement1 , 19 , atoll ( row [ 18 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // retries
rc = sqlite3_bind_int64 ( statement1 , 20 , atoll ( row [ 19 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // delay
rc = sqlite3_bind_int64 ( statement1 , 21 , atoll ( row [ 20 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // next_query_flagIN
rc = sqlite3_bind_int64 ( statement1 , 22 , atoll ( row [ 21 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // mirror_flagOUT
rc = sqlite3_bind_int64 ( statement1 , 23 , atoll ( row [ 22 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // mirror_hostgroup
rc = sqlite3_bind_text ( statement1 , 24 , row [ 23 ] , - 1 , SQLITE_TRANSIENT ) ; assert ( rc = = SQLITE_OK ) ; // error_msg
rc = sqlite3_bind_text ( statement1 , 25 , row [ 24 ] , - 1 , SQLITE_TRANSIENT ) ; assert ( rc = = SQLITE_OK ) ; // OK_msg
rc = sqlite3_bind_int64 ( statement1 , 26 , atoll ( row [ 25 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // sticky_conn
rc = sqlite3_bind_int64 ( statement1 , 27 , atoll ( row [ 26 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // multiplex
rc = sqlite3_bind_int64 ( statement1 , 28 , atoll ( row [ 27 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // log
rc = sqlite3_bind_int64 ( statement1 , 29 , atoll ( row [ 28 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // apply
rc = sqlite3_bind_text ( statement1 , 30 , row [ 29 ] , - 1 , SQLITE_TRANSIENT ) ; assert ( rc = = SQLITE_OK ) ; // comment
SAFE_SQLITE3_STEP ( statement1 ) ;
rc = sqlite3_clear_bindings ( statement1 ) ; assert ( rc = = SQLITE_OK ) ;
rc = sqlite3_reset ( statement1 ) ; assert ( rc = = SQLITE_OK ) ;
}
mysql_free_result ( result ) ;
proxy_info ( " Cluster: Fetching MySQL Query Rules from peer %s:%d completed \n " , hostname , port ) ;
proxy_info ( " Cluster: Loading to runtime MySQL Servers from peer %s:%d \n " , hostname , port ) ;
GloAdmin - > load_mysql_query_rules_to_runtime ( ) ;
if ( __sync_fetch_and_add ( & GloProxyCluster - > cluster_mysql_query_rules_save_to_disk , 0 ) = = true ) {
proxy_info ( " Cluster: Saving to disk MySQL Query Rules from peer %s:%d \n " , hostname , port ) ;
GloAdmin - > flush_mysql_query_rules__from_memory_to_disk ( ) ;
}
} else {
proxy_info ( " Cluster: Fetching MySQL Query Rules from peer %s:%d failed: %s \n " , hostname , port , mysql_error ( conn ) ) ;
}
} else {
proxy_info ( " Cluster: Fetching MySQL Query Rules from peer %s:%d failed: %s \n " , hostname , port , mysql_error ( conn ) ) ;
}
}
__exit_pull_mysql_query_rules_from_peer :
if ( conn ) {
if ( conn - > net . vio ) {
mysql_close ( conn ) ;
}
}
free ( hostname ) ;
}
pthread_mutex_unlock ( & GloProxyCluster - > update_mysql_query_rules_mutex ) ;
}
void ProxySQL_Cluster : : pull_mysql_users_from_peer ( ) {
char * hostname = NULL ;
uint16_t port = 0 ;
pthread_mutex_lock ( & GloProxyCluster - > update_mysql_users_mutex ) ;
nodes . get_peer_to_sync_mysql_users ( & hostname , & port ) ;
if ( hostname ) {
char * username = NULL ;
char * password = NULL ;
bool rc_bool = true ;
MYSQL * rc_conn ;
int rc_query ;
int rc ;
MYSQL * conn = mysql_init ( NULL ) ;
if ( conn = = NULL ) {
proxy_error ( " Unable to run mysql_init() \n " ) ;
goto __exit_pull_mysql_users_from_peer ;
}
GloProxyCluster - > get_credentials ( & username , & password ) ;
if ( strlen ( username ) ) { // do not monitor if the username is empty
unsigned int timeout = 1 ;
unsigned int timeout_long = 60 ;
mysql_options ( conn , MYSQL_OPT_CONNECT_TIMEOUT , & timeout ) ;
mysql_options ( conn , MYSQL_OPT_READ_TIMEOUT , & timeout_long ) ;
mysql_options ( conn , MYSQL_OPT_WRITE_TIMEOUT , & timeout ) ;
proxy_info ( " Cluster: Fetching MySQL Users from peer %s:%d started \n " , hostname , port ) ;
rc_conn = mysql_real_connect ( conn , hostname , username , password , NULL , port , NULL , 0 ) ;
if ( rc_conn ) {
rc_query = mysql_query ( conn , " SELECT username, password, active, use_ssl, default_hostgroup, default_schema, schema_locked, transaction_persistent, fast_forward, backend, frontend, max_connections FROM runtime_mysql_users " ) ;
if ( rc_query = = 0 ) {
MYSQL_RES * result = mysql_store_result ( conn ) ;
GloAdmin - > admindb - > execute ( " DELETE FROM mysql_users " ) ;
MYSQL_ROW row ;
char * q = ( char * ) " INSERT INTO mysql_users (username, password, active, use_ssl, default_hostgroup, default_schema, schema_locked, transaction_persistent, fast_forward, backend, frontend, max_connections) VALUES (?1 , ?2 , ?3 , ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12) " ;
sqlite3_stmt * statement1 = NULL ;
sqlite3 * mydb3 = GloAdmin - > admindb - > get_db ( ) ;
rc = sqlite3_prepare_v2 ( mydb3 , q , - 1 , & statement1 , 0 ) ;
assert ( rc = = SQLITE_OK ) ;
while ( ( row = mysql_fetch_row ( result ) ) ) {
rc = sqlite3_bind_text ( statement1 , 1 , row [ 0 ] , - 1 , SQLITE_TRANSIENT ) ; assert ( rc = = SQLITE_OK ) ; // username
rc = sqlite3_bind_text ( statement1 , 2 , row [ 1 ] , - 1 , SQLITE_TRANSIENT ) ; assert ( rc = = SQLITE_OK ) ; // password
rc = sqlite3_bind_int64 ( statement1 , 3 , atoll ( row [ 2 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // active
rc = sqlite3_bind_int64 ( statement1 , 4 , atoll ( row [ 3 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // use_ssl
rc = sqlite3_bind_int64 ( statement1 , 5 , atoll ( row [ 4 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // default_hostgroup
rc = sqlite3_bind_text ( statement1 , 6 , row [ 5 ] , - 1 , SQLITE_TRANSIENT ) ; assert ( rc = = SQLITE_OK ) ; // default_schema
rc = sqlite3_bind_int64 ( statement1 , 7 , atoll ( row [ 6 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // schema_locked
rc = sqlite3_bind_int64 ( statement1 , 8 , atoll ( row [ 7 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // transaction_persistent
rc = sqlite3_bind_int64 ( statement1 , 9 , atoll ( row [ 8 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // fast_forward
rc = sqlite3_bind_int64 ( statement1 , 10 , atoll ( row [ 9 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // backend
rc = sqlite3_bind_int64 ( statement1 , 11 , atoll ( row [ 10 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // frontend
rc = sqlite3_bind_int64 ( statement1 , 12 , atoll ( row [ 11 ] ) ) ; assert ( rc = = SQLITE_OK ) ; // max_connection
SAFE_SQLITE3_STEP ( statement1 ) ;
rc = sqlite3_clear_bindings ( statement1 ) ; assert ( rc = = SQLITE_OK ) ;
rc = sqlite3_reset ( statement1 ) ; assert ( rc = = SQLITE_OK ) ;
}
mysql_free_result ( result ) ;
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 ( __sync_fetch_and_add ( & GloProxyCluster - > cluster_mysql_query_rules_save_to_disk , 0 ) = = true ) {
proxy_info ( " Cluster: Saving to disk MySQL Query Rules from peer %s:%d \n " , hostname , port ) ;
GloAdmin - > flush_mysql_users__from_memory_to_disk ( ) ;
}
} else {
proxy_info ( " Cluster: Fetching MySQL Users from peer %s:%d failed: %s \n " , hostname , port , mysql_error ( conn ) ) ;
}
} else {
proxy_info ( " Cluster: Fetching MySQL Users from peer %s:%d failed: %s \n " , hostname , port , mysql_error ( conn ) ) ;
}
}
__exit_pull_mysql_users_from_peer :
if ( conn ) {
if ( conn - > net . vio ) {
mysql_close ( conn ) ;
}
}
free ( hostname ) ;
}
pthread_mutex_unlock ( & GloProxyCluster - > update_mysql_users_mutex ) ;
}
void ProxySQL_Cluster : : pull_mysql_servers_from_peer ( ) {
char * hostname = NULL ;
uint16_t port = 0 ;
pthread_mutex_lock ( & GloProxyCluster - > update_mysql_servers_mutex ) ;
nodes . get_peer_to_sync_mysql_servers ( & hostname , & port ) ;
if ( hostname ) {
char * username = NULL ;
char * password = NULL ;
bool rc_bool = true ;
MYSQL * rc_conn ;
int rc_query ;
MYSQL * conn = mysql_init ( NULL ) ;
if ( conn = = NULL ) {
proxy_error ( " Unable to run mysql_init() \n " ) ;
goto __exit_pull_mysql_servers_from_peer ;
}
GloProxyCluster - > get_credentials ( & username , & password ) ;
if ( strlen ( username ) ) { // do not monitor if the username is empty
unsigned int timeout = 1 ;
unsigned int timeout_long = 60 ;
mysql_options ( conn , MYSQL_OPT_CONNECT_TIMEOUT , & timeout ) ;
mysql_options ( conn , MYSQL_OPT_READ_TIMEOUT , & timeout_long ) ;
mysql_options ( conn , MYSQL_OPT_WRITE_TIMEOUT , & timeout ) ;
proxy_info ( " Cluster: Fetching MySQL Servers from peer %s:%d started \n " , hostname , port ) ;
rc_conn = mysql_real_connect ( conn , hostname , username , password , NULL , port , NULL , 0 ) ;
if ( rc_conn ) {
rc_query = mysql_query ( conn , " SELECT hostgroup_id, hostname, port, status, weight, compression, max_connections, max_replication_lag, use_ssl, max_latency_ms, comment FROM runtime_mysql_servers " ) ;
if ( rc_query = = 0 ) {
MYSQL_RES * result = mysql_store_result ( conn ) ;
GloAdmin - > admindb - > execute ( " DELETE FROM mysql_servers " ) ;
MYSQL_ROW row ;
char * q = ( char * ) " INSERT INTO mysql_servers (hostgroup_id, hostname, port, status, weight, compression, max_connections, max_replication_lag, use_ssl, max_latency_ms, comment) VALUES (%s, \" %s \" , %s, \" %s \" , %s, %s, %s, %s, %s, %s, '%s') " ;
while ( ( row = mysql_fetch_row ( result ) ) ) {
int i ;
int l = 0 ;
for ( i = 0 ; i < 10 ; i + + ) {
l + = strlen ( row [ i ] ) ;
}
char * o = escape_string_single_quotes ( row [ 10 ] , false ) ;
char * query = ( char * ) malloc ( strlen ( q ) + i + strlen ( o ) + 64 ) ;
sprintf ( query , q , row [ 0 ] , row [ 1 ] , row [ 2 ] , row [ 3 ] , row [ 4 ] , row [ 5 ] , row [ 6 ] , row [ 7 ] , row [ 8 ] , row [ 9 ] , o ) ;
if ( o ! = row [ 10 ] ) { // there was a copy
free ( o ) ;
}
GloAdmin - > admindb - > execute ( query ) ;
free ( query ) ;
}
mysql_free_result ( result ) ;
rc_query = mysql_query ( conn , " SELECT writer_hostgroup, reader_hostgroup, comment FROM mysql_replication_hostgroups " ) ;
if ( rc_query = = 0 ) {
MYSQL_RES * result = mysql_store_result ( conn ) ;
GloAdmin - > admindb - > execute ( " DELETE FROM mysql_replication_hostgroups " ) ;
MYSQL_ROW row ;
char * q = ( char * ) " INSERT INTO mysql_replication_hostgroups (writer_hostgroup, reader_hostgroup, comment) VALUES (%s, %s, '%s') " ;
while ( ( row = mysql_fetch_row ( result ) ) ) {
int i ;
int l = 0 ;
for ( i = 0 ; i < 2 ; i + + ) {
l + = strlen ( row [ i ] ) ;
}
char * o = escape_string_single_quotes ( row [ 2 ] , false ) ;
char * query = ( char * ) malloc ( strlen ( q ) + i + strlen ( o ) + 64 ) ;
sprintf ( query , q , row [ 0 ] , row [ 1 ] , o ) ;
if ( o ! = row [ 2 ] ) { // there was a copy
free ( o ) ;
}
GloAdmin - > admindb - > execute ( query ) ;
free ( query ) ;
}
mysql_free_result ( result ) ;
proxy_info ( " Cluster: Fetching MySQL Servers from peer %s:%d completed \n " , hostname , port ) ;
proxy_info ( " Cluster: Loading to runtime MySQL Servers from peer %s:%d \n " , hostname , port ) ;
GloAdmin - > load_mysql_servers_to_runtime ( ) ;
if ( __sync_fetch_and_add ( & GloProxyCluster - > cluster_mysql_servers_save_to_disk , 0 ) = = true ) {
proxy_info ( " Cluster: Saving to disk MySQL Servers from peer %s:%d \n " , hostname , port ) ;
GloAdmin - > flush_mysql_servers__from_memory_to_disk ( ) ;
}
} else {
proxy_info ( " Cluster: Fetching MySQL Servers from peer %s:%d failed: %s \n " , hostname , port , mysql_error ( conn ) ) ;
}
} else {
proxy_info ( " Cluster: Fetching MySQL Servers from peer %s:%d failed: %s \n " , hostname , port , mysql_error ( conn ) ) ;
}
} else {
proxy_info ( " Cluster: Fetching MySQL Servers from peer %s:%d failed: %s \n " , hostname , port , mysql_error ( conn ) ) ;
}
}
__exit_pull_mysql_servers_from_peer :
if ( conn ) {
if ( conn - > net . vio ) {
mysql_close ( conn ) ;
}
}
free ( hostname ) ;
}
pthread_mutex_unlock ( & GloProxyCluster - > update_mysql_servers_mutex ) ;
}
void ProxySQL_Cluster : : pull_proxysql_servers_from_peer ( ) {
char * hostname = NULL ;
uint16_t port = 0 ;
pthread_mutex_lock ( & GloProxyCluster - > update_proxysql_servers_mutex ) ;
nodes . get_peer_to_sync_proxysql_servers ( & hostname , & port ) ;
if ( hostname ) {
char * username = NULL ;
char * password = NULL ;
bool rc_bool = true ;
MYSQL * rc_conn ;
int rc_query ;
MYSQL * conn = mysql_init ( NULL ) ;
if ( conn = = NULL ) {
proxy_error ( " Unable to run mysql_init() \n " ) ;
goto __exit_pull_proxysql_servers_from_peer ;
}
GloProxyCluster - > get_credentials ( & username , & password ) ;
if ( strlen ( username ) ) { // do not monitor if the username is empty
unsigned int timeout = 1 ;
unsigned int timeout_long = 60 ;
mysql_options ( conn , MYSQL_OPT_CONNECT_TIMEOUT , & timeout ) ;
mysql_options ( conn , MYSQL_OPT_READ_TIMEOUT , & timeout_long ) ;
mysql_options ( conn , MYSQL_OPT_WRITE_TIMEOUT , & timeout ) ;
proxy_info ( " Cluster: Fetching ProxySQL Servers from peer %s:%d started \n " , hostname , port ) ;
rc_conn = mysql_real_connect ( conn , hostname , username , password , NULL , port , NULL , 0 ) ;
if ( rc_conn ) {
rc_query = mysql_query ( conn , " SELECT hostname, port, weight, comment FROM runtime_proxysql_servers " ) ;
if ( rc_query = = 0 ) {
MYSQL_RES * result = mysql_store_result ( conn ) ;
GloAdmin - > admindb - > execute ( " DELETE FROM proxysql_servers " ) ;
MYSQL_ROW row ;
char * q = ( char * ) " INSERT INTO proxysql_servers (hostname, port, weight, comment) VALUES ( \" %s \" , %s, %s, '%s') " ;
while ( ( row = mysql_fetch_row ( result ) ) ) {
int i ;
int l = 0 ;
for ( i = 0 ; i < 3 ; i + + ) {
l + = strlen ( row [ i ] ) ;
}
char * o = escape_string_single_quotes ( row [ 3 ] , false ) ;
char * query = ( char * ) malloc ( strlen ( q ) + i + strlen ( o ) + 64 ) ;
sprintf ( query , q , row [ 0 ] , row [ 1 ] , row [ 2 ] , o ) ;
if ( o ! = row [ 3 ] ) { // there was a copy
free ( o ) ;
}
GloAdmin - > admindb - > execute ( query ) ;
free ( query ) ;
}
mysql_free_result ( result ) ;
proxy_info ( " Cluster: Fetching ProxySQL Servers from peer %s:%d completed \n " , hostname , port ) ;
proxy_info ( " Cluster: Loading to runtime ProxySQL Servers from peer %s:%d \n " , hostname , port ) ;
GloAdmin - > load_proxysql_servers_to_runtime ( false ) ;
if ( __sync_fetch_and_add ( & GloProxyCluster - > cluster_proxysql_servers_save_to_disk , 0 ) = = true ) {
proxy_info ( " Cluster: Saving to disk ProxySQL Servers from peer %s:%d \n " , hostname , port ) ;
GloAdmin - > flush_proxysql_servers__from_memory_to_disk ( ) ;
}
} else {
proxy_info ( " Cluster: Fetching ProxySQL Servers from peer %s:%d failed: %s \n " , hostname , port , mysql_error ( conn ) ) ;
}
} else {
proxy_info ( " Cluster: Fetching ProxySQL Servers from peer %s:%d failed: %s \n " , hostname , port , mysql_error ( conn ) ) ;
}
}
__exit_pull_proxysql_servers_from_peer :
if ( conn ) {
if ( conn - > net . vio ) {
mysql_close ( conn ) ;
}
}
free ( hostname ) ;
}
pthread_mutex_unlock ( & GloProxyCluster - > update_proxysql_servers_mutex ) ;
}
void ProxySQL_Node_Entry : : set_metrics ( MYSQL_RES * _r , unsigned long long _response_time ) {
@ -487,8 +982,9 @@ uint64_t ProxySQL_Cluster_Nodes::generate_hash(char *_hostname, uint16_t _port)
return hash_ ;
}
void ProxySQL_Cluster_Nodes : : load_servers_list ( SQLite3_result * resultset ) {
pthread_mutex_lock ( & mutex ) ;
void ProxySQL_Cluster_Nodes : : load_servers_list ( SQLite3_result * resultset , bool _lock ) {
if ( _lock )
pthread_mutex_lock ( & mutex ) ;
set_all_inactive ( ) ;
for ( std : : vector < SQLite3_row * > : : iterator it = resultset - > rows . begin ( ) ; it ! = resultset - > rows . end ( ) ; + + it ) {
SQLite3_row * r = * it ;
@ -521,7 +1017,8 @@ void ProxySQL_Cluster_Nodes::load_servers_list(SQLite3_result *resultset) {
}
}
remove_inactives ( ) ;
pthread_mutex_unlock ( & mutex ) ;
if ( _lock )
pthread_mutex_unlock ( & mutex ) ;
}
// if it returns false , the node doesn't exist anymore and the monitor should stop
@ -578,6 +1075,130 @@ bool ProxySQL_Cluster_Nodes::Update_Node_Metrics(char * _h, uint16_t _p, MYSQL_R
return ret ;
}
void ProxySQL_Cluster_Nodes : : get_peer_to_sync_mysql_query_rules ( char * * host , uint16_t * port ) {
unsigned long long version = 0 ;
unsigned long long epoch = 0 ;
char * hostname = NULL ;
uint16_t p = 0 ;
// pthread_mutex_lock(&mutex);
//unsigned long long curtime = monotonic_time();
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 . mysql_query_rules ;
if ( v - > version > 1 ) {
if ( v - > epoch > epoch & & v - > diff_check > 3 ) {
epoch = v - > epoch ;
version = v - > version ;
if ( hostname ) {
free ( hostname ) ;
}
hostname = strdup ( node - > get_hostname ( ) ) ;
p = node - > get_port ( ) ;
}
}
it + + ;
}
// pthread_mutex_unlock(&mutex);
if ( hostname ) {
* host = hostname ;
* port = p ;
}
proxy_info ( " Cluster: detected peer %s:%d with mysql_query_rules version %llu, epoch %llu \n " , hostname , p , version , epoch ) ;
}
void ProxySQL_Cluster_Nodes : : get_peer_to_sync_mysql_servers ( char * * host , uint16_t * port ) {
unsigned long long version = 0 ;
unsigned long long epoch = 0 ;
char * hostname = NULL ;
uint16_t p = 0 ;
// pthread_mutex_lock(&mutex);
//unsigned long long curtime = monotonic_time();
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 . mysql_servers ;
if ( v - > version > 1 ) {
if ( v - > epoch > epoch & & v - > diff_check > 3 ) {
epoch = v - > epoch ;
version = v - > version ;
if ( hostname ) {
free ( hostname ) ;
}
hostname = strdup ( node - > get_hostname ( ) ) ;
p = node - > get_port ( ) ;
}
}
it + + ;
}
// pthread_mutex_unlock(&mutex);
if ( hostname ) {
* host = hostname ;
* port = p ;
}
proxy_info ( " Cluster: detected peer %s:%d with mysql_servers version %llu, epoch %llu \n " , hostname , p , version , epoch ) ;
}
void ProxySQL_Cluster_Nodes : : get_peer_to_sync_mysql_users ( char * * host , uint16_t * port ) {
unsigned long long version = 0 ;
unsigned long long epoch = 0 ;
char * hostname = NULL ;
uint16_t p = 0 ;
// pthread_mutex_lock(&mutex);
//unsigned long long curtime = monotonic_time();
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 . mysql_users ;
if ( v - > version > 1 ) {
if ( v - > epoch > epoch & & v - > diff_check > 3 ) {
epoch = v - > epoch ;
version = v - > version ;
if ( hostname ) {
free ( hostname ) ;
}
hostname = strdup ( node - > get_hostname ( ) ) ;
p = node - > get_port ( ) ;
}
}
it + + ;
}
// pthread_mutex_unlock(&mutex);
if ( hostname ) {
* host = hostname ;
* port = p ;
}
proxy_info ( " Cluster: detected peer %s:%d with mysql_users 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 ;
char * hostname = NULL ;
uint16_t p = 0 ;
// pthread_mutex_lock(&mutex);
//unsigned long long curtime = monotonic_time();
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 . proxysql_servers ;
if ( v - > version > 1 ) {
if ( v - > epoch > epoch & & v - > diff_check > 3 ) {
epoch = v - > epoch ;
version = v - > version ;
if ( hostname ) {
free ( hostname ) ;
}
hostname = strdup ( node - > get_hostname ( ) ) ;
p = node - > get_port ( ) ;
}
}
it + + ;
}
// pthread_mutex_unlock(&mutex);
if ( hostname ) {
* host = hostname ;
* port = p ;
}
proxy_info ( " Cluster: detected peer %s:%d with proxysql_servers version %llu, epoch %llu \n " , hostname , p , version , epoch ) ;
}
SQLite3_result * ProxySQL_Cluster_Nodes : : stats_proxysql_servers_checksums ( ) {
const int colnum = 9 ;
SQLite3_result * result = new SQLite3_result ( colnum ) ;
@ -746,10 +1367,22 @@ SQLite3_result * ProxySQL_Cluster_Nodes::dump_table_proxysql_servers() {
ProxySQL_Cluster : : ProxySQL_Cluster ( ) {
pthread_mutex_init ( & mutex , NULL ) ;
pthread_mutex_init ( & update_mysql_query_rules_mutex , NULL ) ;
pthread_mutex_init ( & update_mysql_servers_mutex , NULL ) ;
pthread_mutex_init ( & update_mysql_users_mutex , NULL ) ;
pthread_mutex_init ( & update_proxysql_servers_mutex , NULL ) ;
cluster_username = strdup ( ( char * ) " " ) ;
cluster_password = strdup ( ( char * ) " " ) ;
cluster_check_interval_ms = 1000 ;
cluster_check_status_frequency = 10 ;
cluster_mysql_query_rules_diffs_before_sync = 3 ;
cluster_mysql_servers_diffs_before_sync = 3 ;
cluster_mysql_users_diffs_before_sync = 3 ;
cluster_proxysql_servers_diffs_before_sync = 3 ;
cluster_mysql_query_rules_save_to_disk = true ;
cluster_mysql_servers_save_to_disk = true ;
cluster_mysql_users_save_to_disk = true ;
cluster_proxysql_servers_save_to_disk = true ;
}
ProxySQL_Cluster : : ~ ProxySQL_Cluster ( ) {