Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update IP address of ProxySQL cluster node on connection failure #4452

Merged
merged 2 commits into from
Feb 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 6 additions & 41 deletions include/ProxySQL_Cluster.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,47 +96,11 @@ class ProxySQL_Node_Address {
char *hostname;
char *admin_mysql_ifaces;
uint16_t port;
ProxySQL_Node_Address(char *h, uint16_t p) : ProxySQL_Node_Address(h, p, NULL) {
// resolving DNS if available in Cache
if (h && p) {
size_t ip_count = 0;
const std::string& ip = MySQL_Monitor::dns_lookup(h, false, &ip_count);

if (ip_count > 1) {
proxy_error("Proxy cluster node '%s' has more than one ('%ld') mapped IP address. It is recommended to provide IP address or domain with one resolvable IP address.\n",
h, ip_count);
}

if (ip.empty() == false) {
ip_addr = strdup(ip.c_str());
}
}
}
ProxySQL_Node_Address(char* h, uint16_t p, char* ip) {
hostname = strdup(h);
ip_addr = NULL;
if (ip) {
ip_addr = strdup(ip);
}
admin_mysql_ifaces = NULL;
port = p;
uuid = NULL;
hash = 0;
}
~ProxySQL_Node_Address() {
if (hostname) free(hostname);
if (uuid) free(uuid);
if (admin_mysql_ifaces) free(admin_mysql_ifaces);
if (ip_addr) free(ip_addr);
}
const char* get_host_address() const {
const char* host_address = hostname;

if (ip_addr)
host_address = ip_addr;

return host_address;
}
ProxySQL_Node_Address(char* h, uint16_t p);
ProxySQL_Node_Address(char* h, uint16_t p, char* ip);
~ProxySQL_Node_Address();
const char* get_host_address() const;
void resolve_hostname();
private:
char* ip_addr;
};
Expand All @@ -163,6 +127,7 @@ class ProxySQL_Node_Entry {
ProxySQL_Node_Entry(char *_hostname, uint16_t _port, uint64_t _weight, char *_comment);
ProxySQL_Node_Entry(char* _hostname, uint16_t _port, uint64_t _weight, char* _comment, char* ip);
~ProxySQL_Node_Entry();
void resolve_hostname();
bool get_active();
void set_active(bool a);
uint64_t get_weight();
Expand Down
85 changes: 72 additions & 13 deletions lib/ProxySQL_Cluster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ void * ProxySQL_Cluster_Monitor_thread(void *args) {
}
} else {
proxy_warning("Cluster: unable to connect to peer %s:%d . Error: %s\n", node->hostname, node->port, mysql_error(conn));
node->resolve_hostname();
mysql_close(conn);
conn = mysql_init(NULL);
int ci = __sync_fetch_and_add(&GloProxyCluster->cluster_check_interval_ms,0);
Expand Down Expand Up @@ -317,19 +318,7 @@ void ProxySQL_Node_Metrics::reset() {
ProxySQL_Node_Entry::ProxySQL_Node_Entry(char *_hostname, uint16_t _port, uint64_t _weight, char * _comment) :
ProxySQL_Node_Entry(_hostname, _port, _weight, _comment, NULL) {
// resolving DNS if available in Cache
if (_hostname && _port) {
size_t ip_count = 0;
const std::string& ip = MySQL_Monitor::dns_lookup(_hostname, false, &ip_count);

if (ip_count > 1) {
proxy_warning("ProxySQL Cluster node '%s' has more than one (%ld) mapped IP address: under some circumstances this may lead to undefined behavior. It is recommended to provide IP address or hostname with only one resolvable IP.\n",
_hostname, ip_count);
}

if (ip.empty() == false) {
ip_addr = strdup(ip.c_str());
}
}
resolve_hostname();
}

ProxySQL_Node_Entry::ProxySQL_Node_Entry(char* _hostname, uint16_t _port, uint64_t _weight, char* _comment, char* ip) {
Expand Down Expand Up @@ -384,6 +373,26 @@ ProxySQL_Node_Entry::~ProxySQL_Node_Entry() {
metrics = NULL;
}

void ProxySQL_Node_Entry::resolve_hostname() {
if (ip_addr) {
free(ip_addr);
ip_addr = NULL;
}
if (hostname && port) {
size_t ip_count = 0;
const std::string& ip = MySQL_Monitor::dns_lookup(hostname, false, &ip_count);

if (ip_count > 1) {
proxy_warning("ProxySQL Cluster node '%s' has more than one (%ld) mapped IP address: under some circumstances this may lead to undefined behavior. It is recommended to provide IP address or hostname with only one resolvable IP.\n",
hostname, ip_count);
}

if (ip.empty() == false) {
ip_addr = strdup(ip.c_str());
}
}
}

bool ProxySQL_Node_Entry::get_active() {
return active;
}
Expand Down Expand Up @@ -2922,6 +2931,7 @@ void ProxySQL_Cluster_Nodes::load_servers_list(SQLite3_result *resultset, bool _
//pthread_detach(a->thrid);
} else {
node = ite->second;
node->resolve_hostname();
node->set_active(true);
node->set_weight(w_);
node->set_comment(c_);
Expand Down Expand Up @@ -4404,3 +4414,52 @@ void ProxySQL_Cluster::join_term_thread() {
}
pthread_mutex_unlock(&mutex);
}

ProxySQL_Node_Address::ProxySQL_Node_Address(char* h, uint16_t p) : ProxySQL_Node_Address(h, p, NULL) {
// resolving DNS if available in Cache
resolve_hostname();
}
ProxySQL_Node_Address::ProxySQL_Node_Address(char* h, uint16_t p, char* ip) {
hostname = strdup(h);
ip_addr = NULL;
if (ip) {
ip_addr = strdup(ip);
}
admin_mysql_ifaces = NULL;
port = p;
uuid = NULL;
hash = 0;
}
ProxySQL_Node_Address::~ProxySQL_Node_Address() {
if (hostname) free(hostname);
if (uuid) free(uuid);
if (admin_mysql_ifaces) free(admin_mysql_ifaces);
if (ip_addr) free(ip_addr);
}
const char* ProxySQL_Node_Address::get_host_address() const {
const char* host_address = hostname;

if (ip_addr)
host_address = ip_addr;

return host_address;
}
void ProxySQL_Node_Address::resolve_hostname() {
if (ip_addr) {
free(ip_addr);
ip_addr = NULL;
}
if (hostname && port) {
size_t ip_count = 0;
const std::string& ip = MySQL_Monitor::dns_lookup(hostname, false, &ip_count);

if (ip_count > 1) {
proxy_error("Proxy cluster node '%s' has more than one ('%ld') mapped IP address. It is recommended to provide IP address or domain with one resolvable IP address.\n",
hostname, ip_count);
}

if (ip.empty() == false) {
ip_addr = strdup(ip.c_str());
}
}
}
Loading