diff --git a/include/MySQL_HostGroups_Manager.h b/include/MySQL_HostGroups_Manager.h index 8f21cb56f..189a78c1e 100644 --- a/include/MySQL_HostGroups_Manager.h +++ b/include/MySQL_HostGroups_Manager.h @@ -402,13 +402,15 @@ class MySQL_HostGroups_Manager { __HGM_TABLES_SIZE }; - std::array table_resultset_checksum; + std::array table_resultset_checksum { 0 }; class HostGroup_Server_Mapping { public: enum Type { WRITER = 0, - READER = 1 + READER = 1, + + __TYPE_SIZE }; struct Node { @@ -418,7 +420,7 @@ class MySQL_HostGroups_Manager { MySerStatus server_status = MYSQL_SERVER_STATUS_OFFLINE_HARD; }; - HostGroup_Server_Mapping() : readonly_flag(1), myHGM(NULL) { } + HostGroup_Server_Mapping(MySQL_HostGroups_Manager* hgm) : readonly_flag(1), myHGM(hgm) { } ~HostGroup_Server_Mapping() = default; // Note: copy, remove, clear method also makes changes to MyHostGroups @@ -452,23 +454,18 @@ class MySQL_HostGroups_Manager { return readonly_flag; } - inline - void set_HGM(MySQL_HostGroups_Manager* hgm) { - myHGM = hgm; - } - private: unsigned int get_hostgroup_id(Type type, size_t index) const; unsigned int get_hostgroup_id(Type type, const Node& node) const; MySrvC* insert_HGM(unsigned int hostgroup_id, const MySrvC* srv); void remove_HGM(MySrvC* srv); - std::array, 2> mapping; + std::array, __TYPE_SIZE> mapping; // index 0 contains reader and 1 contains writer hostgroups int readonly_flag; MySQL_HostGroups_Manager* myHGM; }; - std::unordered_map hostgroup_server_mapping; + std::unordered_map> hostgroup_server_mapping; uint64_t hgsm_mysql_servers_checksum = 0; uint64_t hgsm_mysql_replication_hostgroups_checksum = 0; diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index ff016f42d..96d52f792 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -1930,6 +1930,7 @@ bool MySQL_HostGroups_Manager::commit( delete resultset; } else { proxy_info("Checksum for table %s is 0x%lX\n", "mysql_servers", (long unsigned int)0); + table_resultset_checksum[HGM_TABLES::MYSQL_SERVERS] = 0; } } @@ -1970,9 +1971,9 @@ bool MySQL_HostGroups_Manager::commit( int affected_rows = 0; SQLite3_result* resultset = NULL; - const char* query = "SELECT DISTINCT hostname, port, '1' is_writer, status, reader_hostgroup, writer_hostgroup, mem_pointer FROM mysql_replication_hostgroups JOIN mysql_servers ON hostgroup_id=writer_hostgroup \ + const char* query = "SELECT DISTINCT hostname, port, '1' is_writer, status, reader_hostgroup, writer_hostgroup, mem_pointer FROM mysql_replication_hostgroups JOIN mysql_servers ON hostgroup_id=writer_hostgroup WHERE status<>3 \ UNION \ - SELECT DISTINCT hostname, port, '0' is_writer, status, reader_hostgroup, writer_hostgroup, mem_pointer FROM mysql_replication_hostgroups JOIN mysql_servers ON hostgroup_id=reader_hostgroup \ + SELECT DISTINCT hostname, port, '0' is_writer, status, reader_hostgroup, writer_hostgroup, mem_pointer FROM mysql_replication_hostgroups JOIN mysql_servers ON hostgroup_id=reader_hostgroup WHERE status<>3 \ ORDER BY hostname, port"; mydb->execute_statement(query, &error, &cols, &affected_rows, &resultset); @@ -1989,8 +1990,18 @@ bool MySQL_HostGroups_Manager::commit( const std::string& server_id = std::string(r->fields[0]) + ":::" + r->fields[1]; if (fetched_server_mapping == NULL || server_id != fetched_server_id) { - fetched_server_mapping = &hostgroup_server_mapping[server_id]; - fetched_server_mapping->set_HGM(this); + + auto itr = hostgroup_server_mapping.find(server_id); + + if (itr == hostgroup_server_mapping.end()) { + std::unique_ptr server_mapping(new HostGroup_Server_Mapping(this)); + fetched_server_mapping = server_mapping.get(); + hostgroup_server_mapping.insert({ server_id, std::move(server_mapping) }); + } + else { + fetched_server_mapping = itr->second.get(); + } + fetched_server_id = server_id; } @@ -4582,27 +4593,12 @@ void MySQL_HostGroups_Manager::read_only_action_v2(const std::listsecond; - - const std::vector& writer_map = host_server_mapping.get(HostGroup_Server_Mapping::Type::WRITER); - const std::vector& reader_map = host_server_mapping.get(HostGroup_Server_Mapping::Type::READER); - - bool removed_offline_server = false; + HostGroup_Server_Mapping* host_server_mapping = itr->second.get(); - for (size_t i = 0; i < writer_map.size();) { - - const HostGroup_Server_Mapping::Node& node = writer_map[i]; - - // remove offline hard server node from writer map - if (node.server_status == MYSQL_SERVER_STATUS_OFFLINE_HARD) { - proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 5, "Removing server %s:%d in hostgroup=%d having status='OFFLINE_HARD'\n", hostname.c_str(), port, node.writer_hostgroup_id); - host_server_mapping.remove(HostGroup_Server_Mapping::Type::WRITER, i); - removed_offline_server = true; - continue; - } + if (!host_server_mapping) + assert(0); - i++; - } + const std::vector& writer_map = host_server_mapping->get(HostGroup_Server_Mapping::Type::WRITER); is_writer = !writer_map.empty(); @@ -4610,14 +4606,14 @@ void MySQL_HostGroups_Manager::read_only_action_v2(const std::listcopy(HostGroup_Server_Mapping::Type::WRITER, HostGroup_Server_Mapping::Type::READER); if (mysql_thread___monitor_writer_is_also_reader) { // server is also a reader, we copy all nodes from writer to reader (previous reader nodes will be reused) - host_server_mapping.copy(HostGroup_Server_Mapping::Type::READER, HostGroup_Server_Mapping::Type::WRITER, false); + host_server_mapping->copy(HostGroup_Server_Mapping::Type::READER, HostGroup_Server_Mapping::Type::WRITER, false); } else { // server can only be a writer - host_server_mapping.clear(HostGroup_Server_Mapping::Type::READER); + host_server_mapping->clear(HostGroup_Server_Mapping::Type::READER); } update_mysql_servers_table = true; @@ -4625,12 +4621,12 @@ void MySQL_HostGroups_Manager::read_only_action_v2(const std::listget_readonly_flag() != 0) { // it is the first time that we detect RO on this server - - act = removed_offline_server; if (act == false) { + const std::vector& reader_map = host_server_mapping->get(HostGroup_Server_Mapping::Type::READER); + for (const auto& reader_node : reader_map) { for (const auto& writer_node : writer_map) { @@ -4648,7 +4644,7 @@ void MySQL_HostGroups_Manager::read_only_action_v2(const std::listset_readonly_flag(0); } } else { // the server was already detected as RO=0 @@ -4658,14 +4654,14 @@ void MySQL_HostGroups_Manager::read_only_action_v2(const std::listcopy(HostGroup_Server_Mapping::Type::WRITER, HostGroup_Server_Mapping::Type::READER); if (mysql_thread___monitor_writer_is_also_reader) { // server is also a reader, we copy all nodes from writer to reader (previous reader nodes will be reused) - host_server_mapping.copy(HostGroup_Server_Mapping::Type::READER, HostGroup_Server_Mapping::Type::WRITER, false); + host_server_mapping->copy(HostGroup_Server_Mapping::Type::READER, HostGroup_Server_Mapping::Type::WRITER, false); } else { // server can only be a writer - host_server_mapping.clear(HostGroup_Server_Mapping::Type::READER); + host_server_mapping->clear(HostGroup_Server_Mapping::Type::READER); } update_mysql_servers_table = true; @@ -4674,10 +4670,10 @@ void MySQL_HostGroups_Manager::read_only_action_v2(const std::listcopy(HostGroup_Server_Mapping::Type::READER, HostGroup_Server_Mapping::Type::WRITER, false); // clearing all writer nodes - host_server_mapping.clear(HostGroup_Server_Mapping::Type::WRITER); + host_server_mapping->clear(HostGroup_Server_Mapping::Type::WRITER); update_mysql_servers_table = true; } @@ -4718,29 +4714,24 @@ void MySQL_HostGroups_Manager::read_only_action_v2(const std::listmyhgc->hid, srv->address, srv->port); srv->status = MYSQL_SERVER_STATUS_OFFLINE_HARD; srv->ConnectionsFree->drop_all_connections(); -} \ No newline at end of file +}