From 353d2a49a5c419afdceeba3626380b66f44d0c8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Tue, 5 Jun 2018 11:41:09 +0200 Subject: [PATCH] Try to use the last node in a Galera Cluster --- include/MySQL_Monitor.hpp | 5 +++ lib/MySQL_HostGroups_Manager.cpp | 20 +++++++++++ lib/MySQL_Monitor.cpp | 58 ++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/include/MySQL_Monitor.hpp b/include/MySQL_Monitor.hpp index bba2acf03..36c280a73 100644 --- a/include/MySQL_Monitor.hpp +++ b/include/MySQL_Monitor.hpp @@ -60,6 +60,10 @@ class Galera_monitor_node { Galera_monitor_node(char *_a, int _p, int _whg); ~Galera_monitor_node(); bool add_entry(unsigned long long _st, unsigned long long _ct, long long _tb, bool _pp, bool _ro, int _local_state, bool _desync, bool _reject, bool _sst_donor_reject, char *_error); // return true if status changed + Galera_status_entry_t *last_entry() { + if (idx_last_entry == -1) return NULL; + return (&last_entries[idx_last_entry]); + } }; typedef struct _MyGR_status_entry_t { @@ -183,6 +187,7 @@ class MySQL_Monitor { void * run(); void populate_monitor_mysql_server_group_replication_log(); void populate_monitor_mysql_server_galera_log(); + char * galera_find_last_node(int); }; #endif /* __CLASS_MYSQL_MONITOR_H */ diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index ff6643509..cbd50761a 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -3945,6 +3945,26 @@ void MySQL_HostGroups_Manager::converge_galera_config(int _writer_hostgroup) { } } } + } else { + if (num_writers == 0 && num_backup_writers == 0) { + proxy_warning("Galera: we couldn't find any healthy node for writer HG %d\n", info->writer_hostgroup); + // ask Monitor to get the status of the whole cluster + char * s0 = GloMyMon->galera_find_last_node(info->writer_hostgroup); + if (s0) { + std::string s = string(s0); + std::size_t found=s.find_last_of(":"); + std::string host=s.substr(0,found); + std::string port=s.substr(found+1); + int port_n = atoi(port.c_str()); + proxy_info("Galera: trying to use server %s:%s as a writer for HG %d\n", host.c_str(), port.c_str(), info->writer_hostgroup); + q=(char *)"UPDATE OR REPLACE mysql_servers_incoming SET status=0, hostgroup_id=%d WHERE hostgroup_id IN (%d, %d, %d, %d) AND hostname='%s' AND port=%d"; + query=(char *)malloc(strlen(q) + s.length() + 512); + sprintf(query,q,info->writer_hostgroup, info->writer_hostgroup, info->backup_writer_hostgroup, info->reader_hostgroup, info->offline_hostgroup, host.c_str(), port_n); + mydb->execute(query); + free(query); + free(s0); + } + } } } } diff --git a/lib/MySQL_Monitor.cpp b/lib/MySQL_Monitor.cpp index d97728413..f8ffc8ab7 100644 --- a/lib/MySQL_Monitor.cpp +++ b/lib/MySQL_Monitor.cpp @@ -2640,3 +2640,61 @@ void MySQL_Monitor::populate_monitor_mysql_server_galera_log() { } pthread_mutex_unlock(&GloMyMon->galera_mutex); } + +char * MySQL_Monitor::galera_find_last_node(int writer_hostgroup) { +/* + sqlite3 *mondb=monitordb->get_db(); + int rc; + //char *query=NULL; + char *query1=NULL; + query1=(char *)"INSERT INTO mysql_server_galera_log VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)"; + sqlite3_stmt *statement1=NULL; +*/ + char *str = NULL; + pthread_mutex_lock(&GloMyMon->galera_mutex); +/* + rc=sqlite3_prepare_v2(mondb, query1, -1, &statement1, 0); + assert(rc==SQLITE_OK); + monitordb->execute((char *)"DELETE FROM mysql_server_galera_log"); +*/ + std::map::iterator it2; + Galera_monitor_node *node=NULL; + Galera_monitor_node *writer_node=NULL; + unsigned int writer_nodes = 0; + unsigned long long curtime = monotonic_time(); + unsigned long long ti = mysql_thread___monitor_galera_healthcheck_interval; + ti *= 2; + std::string s = ""; + for (it2=GloMyMon->Galera_Hosts_Map.begin(); it2!=GloMyMon->Galera_Hosts_Map.end(); ++it2) { + node=it2->second; + if (node->writer_hostgroup == writer_hostgroup) { + Galera_status_entry_t * st = node->last_entry(); + if (st) { + if (st->start_time >= curtime - ti) { // only consider recent checks + if (st->error == NULL) { // no check error + if (st->read_only == false) { // the server is writable (this check is arguable) + if (st->wsrep_sst_donor_rejects_queries == false) { + if (writer_nodes == 0) { + s=it2->first; + writer_node = node; + } + writer_nodes++; + } + } + } + } + } + } + } + if (writer_node && writer_nodes == 1) { + // we have only one node let + // we don't care if status + str = strdup(s.c_str()); +/* + std::size_t found=s.find_last_of(":"); + std::string host=s.substr(0,found); + std::string port=s.substr(found+1); +*/ + } + pthread_mutex_unlock(&GloMyMon->galera_mutex); +}