Some improvements and fixes

pull/4127/head
Rahim Kanji 3 years ago
parent 0d86d0aa48
commit e0e06711d8

@ -402,13 +402,15 @@ class MySQL_HostGroups_Manager {
__HGM_TABLES_SIZE
};
std::array<uint64_t, __HGM_TABLES_SIZE> table_resultset_checksum;
std::array<uint64_t, __HGM_TABLES_SIZE> 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<std::vector<Node>, 2> mapping;
std::array<std::vector<Node>, __TYPE_SIZE> mapping; // index 0 contains reader and 1 contains writer hostgroups
int readonly_flag;
MySQL_HostGroups_Manager* myHGM;
};
std::unordered_map<std::string, HostGroup_Server_Mapping> hostgroup_server_mapping;
std::unordered_map<std::string, std::unique_ptr<HostGroup_Server_Mapping>> hostgroup_server_mapping;
uint64_t hgsm_mysql_servers_checksum = 0;
uint64_t hgsm_mysql_replication_hostgroups_checksum = 0;

@ -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<HostGroup_Server_Mapping> 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::list<std::tuple<st
continue;
}
HostGroup_Server_Mapping& host_server_mapping = itr->second;
const std::vector<HostGroup_Server_Mapping::Node>& writer_map = host_server_mapping.get(HostGroup_Server_Mapping::Type::WRITER);
const std::vector<HostGroup_Server_Mapping::Node>& 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<HostGroup_Server_Mapping::Node>& 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::list<std::tuple<st
if (is_writer == false) {
// the server has read_only=0 (writer), but we can't find any writer,
// so we copy all reader nodes to writer
host_server_mapping.copy(HostGroup_Server_Mapping::Type::WRITER, HostGroup_Server_Mapping::Type::READER);
host_server_mapping->copy(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::list<std::tuple<st
bool act = false;
// if the server was RO=0 on the previous check then no action is needed
if (host_server_mapping.get_readonly_flag() != 0) {
if (host_server_mapping->get_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<HostGroup_Server_Mapping::Node>& 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::list<std::tuple<st
if (act == false) {
// no action required, therefore we set readonly_flag to 0
proxy_info("read_only_action_v2() detected RO=0 on server %s:%d for the first time after commit(), but no need to reconfigure\n", hostname.c_str(), port);
host_server_mapping.set_readonly_flag(0);
host_server_mapping->set_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::list<std::tuple<st
if (act == true) { // there are servers either missing, or with stats=OFFLINE_HARD
// copy all reader nodes to writer
host_server_mapping.copy(HostGroup_Server_Mapping::Type::WRITER, HostGroup_Server_Mapping::Type::READER);
host_server_mapping->copy(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::list<std::tuple<st
} else if (read_only == 1) {
if (is_writer) {
// the server has read_only=1 (reader), but we find it as writer, so we copy all writer nodes 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);
// 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::list<std::tuple<st
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;
hgsm_mysql_servers_checksum = 0;
}
uint64_t hash = 0, hash2 = 0;
SpookyHash myhash;
bool init = false;
myhash.Init(19, 3);
hash = table_resultset_checksum[HGM_TABLES::MYSQL_SERVERS];
myhash.Update(&hash, sizeof(hash));
hash = table_resultset_checksum[HGM_TABLES::MYSQL_REPLICATION_HOSTGROUPS];
myhash.Update(&hash, sizeof(hash));
hash = table_resultset_checksum[HGM_TABLES::MYSQL_GROUP_REPLICATION_HOSTGROUPS];
myhash.Update(&hash, sizeof(hash));
hash = table_resultset_checksum[HGM_TABLES::MYSQL_GALERA_HOSTGROUPS];
myhash.Update(&hash, sizeof(hash));
hash = table_resultset_checksum[HGM_TABLES::MYSQL_AWS_AURORA_HOSTGROUPS];
myhash.Update(&hash, sizeof(hash));
for (uint64_t hash_val : table_resultset_checksum) {
if (hash_val) {
if (init == false) {
init = true;
myhash.Init(19, 3);
}
hash = table_resultset_checksum[HGM_TABLES::MYSQL_HOSTGROUP_ATTRIBUTES];
myhash.Update(&hash, sizeof(hash));
myhash.Update(&hash_val, sizeof(hash_val));
}
}
myhash.Final(&hash, &hash2);
@ -4767,7 +4758,7 @@ void MySQL_HostGroups_Manager::read_only_action_v2(const std::list<std::tuple<st
unsigned long long curtime2 = monotonic_time();
curtime1 = curtime1 / 1000;
curtime2 = curtime2 / 1000;
proxy_info("MySQL_HostGroups_Manager::read_only_action_v2() locked for %llums (server count:%ld)\n", curtime2 - curtime1, mysql_servers.size());
proxy_debug(PROXY_DEBUG_MONITOR, 7, "MySQL_HostGroups_Manager::read_only_action_v2() locked for %llums (server count:%ld)\n", curtime2 - curtime1, mysql_servers.size());
}
// shun_and_killall
@ -7755,4 +7746,4 @@ void MySQL_HostGroups_Manager::HostGroup_Server_Mapping::remove_HGM(MySrvC* srv)
proxy_warning("Removed server at address %p, hostgroup %d, address %s port %d. Setting status OFFLINE HARD and immediately dropping all free connections. Used connections will be dropped when trying to use them\n", (void*)srv, srv->myhgc->hid, srv->address, srv->port);
srv->status = MYSQL_SERVER_STATUS_OFFLINE_HARD;
srv->ConnectionsFree->drop_all_connections();
}
}

Loading…
Cancel
Save