From e5cfc2570131f83197a885588af03b8918321a22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Thu, 14 Jun 2018 08:58:23 +0200 Subject: [PATCH] Prevent loading new Galera configuration if leading to a no-op This is to prevent cases in which only one node is left, but from its status it should be offline. ProxySQL would normally set it offline and then back online. This commit prevents it to change status twice. --- lib/MySQL_HostGroups_Manager.cpp | 91 +++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 25 deletions(-) diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index c5226ea9e..b093661b9 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -3633,34 +3633,75 @@ void MySQL_HostGroups_Manager::update_galera_set_offline(char *_hostname, int _p mydb->execute(query); //free(query); converge_galera_config(_writer_hostgroup); - commit(); - wrlock(); - SQLite3_result *resultset2=NULL; - q=(char *)"SELECT writer_hostgroup, backup_writer_hostgroup, reader_hostgroup, offline_hostgroup FROM mysql_galera_hostgroups WHERE writer_hostgroup=%d"; - //query=(char *)malloc(strlen(q)+strlen(_hostname)+64); - sprintf(query,q,_port,_writer_hostgroup); - mydb->execute_statement(query, &error, &cols , &affected_rows , &resultset2); - if (resultset2) { - if (resultset2->rows_count) { - for (std::vector::iterator it = resultset2->rows.begin() ; it != resultset2->rows.end(); ++it) { - SQLite3_row *r=*it; - int writer_hostgroup=atoi(r->fields[0]); - int backup_writer_hostgroup=atoi(r->fields[1]); - int reader_hostgroup=atoi(r->fields[2]); - int offline_hostgroup=atoi(r->fields[3]); - q=(char *)"DELETE FROM mysql_servers WHERE hostgroup_id IN (%d , %d , %d , %d)"; - sprintf(query,q,_port,_writer_hostgroup); - mydb->execute(query); - generate_mysql_servers_table(&writer_hostgroup); - generate_mysql_servers_table(&backup_writer_hostgroup); - generate_mysql_servers_table(&reader_hostgroup); - generate_mysql_servers_table(&offline_hostgroup); + uint64_t checksum_current = 0; + uint64_t checksum_incoming = 0; + { + int cols=0; + int affected_rows=0; + SQLite3_result *resultset_servers=NULL; + char *query=NULL; + char *q1 = NULL; + char *q2 = NULL; + char *error=NULL; + q1 = (char *)"SELECT DISTINCT hostgroup_id, hostname, port, gtid_port, weight, status, compression, max_connections, max_replication_lag, use_ssl, max_latency_ms, comment FROM mysql_servers JOIN mysql_galera_hostgroups ON hostgroup_id=writer_hostgroup OR hostgroup_id=backup_writer_hostgroup OR hostgroup_id=reader_hostgroup WHERE WHERE writer_hostgroup=%d ORDER BY hostgroup_id, hostname, port"; + q2 = (char *)"SELECT DISTINCT hostgroup_id, hostname, port, gtid_port, weight, status, compression, max_connections, max_replication_lag, use_ssl, max_latency_ms, comment FROM mysql_servers_incoming JOIN mysql_galera_hostgroups ON hostgroup_id=writer_hostgroup OR hostgroup_id=backup_writer_hostgroup OR hostgroup_id=reader_hostgroup WHERE WHERE writer_hostgroup=%d ORDER BY hostgroup_id, hostname, port"; + query = (char *)malloc(strlen(q2)+128); + sprintf(query,q1,_writer_hostgroup); + mydb->execute_statement(query, &error , &cols , &affected_rows , &resultset_servers); + if (error = NULL) { + if (resultset_servers) { + checksum_current = resultset_servers->raw_checksum(); } } - delete resultset2; - resultset2=NULL; + if (resultset_servers) { + delete resultset_servers; + resultset_servers = NULL; + } + sprintf(query,q2,_writer_hostgroup); + mydb->execute_statement(query, &error , &cols , &affected_rows , &resultset_servers); + if (error = NULL) { + if (resultset_servers) { + checksum_incoming = resultset_servers->raw_checksum(); + } + } + if (resultset_servers) { + delete resultset_servers; + resultset_servers = NULL; + } + free(query); + } + if (checksum_current && checksum_incoming && (checksum_incoming!=checksum_current)) { + commit(); + wrlock(); + SQLite3_result *resultset2=NULL; + q=(char *)"SELECT writer_hostgroup, backup_writer_hostgroup, reader_hostgroup, offline_hostgroup FROM mysql_galera_hostgroups WHERE writer_hostgroup=%d"; + //query=(char *)malloc(strlen(q)+strlen(_hostname)+64); + sprintf(query,q,_port,_writer_hostgroup); + mydb->execute_statement(query, &error, &cols , &affected_rows , &resultset2); + if (resultset2) { + if (resultset2->rows_count) { + for (std::vector::iterator it = resultset2->rows.begin() ; it != resultset2->rows.end(); ++it) { + SQLite3_row *r=*it; + int writer_hostgroup=atoi(r->fields[0]); + int backup_writer_hostgroup=atoi(r->fields[1]); + int reader_hostgroup=atoi(r->fields[2]); + int offline_hostgroup=atoi(r->fields[3]); + q=(char *)"DELETE FROM mysql_servers WHERE hostgroup_id IN (%d , %d , %d , %d)"; + sprintf(query,q,_port,_writer_hostgroup); + mydb->execute(query); + generate_mysql_servers_table(&writer_hostgroup); + generate_mysql_servers_table(&backup_writer_hostgroup); + generate_mysql_servers_table(&reader_hostgroup); + generate_mysql_servers_table(&offline_hostgroup); + } + } + delete resultset2; + resultset2=NULL; + } + wrunlock(); + } else { + proxy_warning("Galera: skipping setting offline node %s:%d from hostroup %d because won't change the list of ONLINE nodes\n", _hostname, _port, _writer_hostgroup); } - wrunlock(); GloAdmin->mysql_servers_wrunlock(); free(query); }