Unverified Commit 94bc26e6 authored by Yossi Gottlieb's avatar Yossi Gottlieb Committed by GitHub
Browse files

Fix duplicate replicas issue. (#8481)

We need to store replicas referenced by their announced address (IP or
address). Before that, if hostnames were used and the IP address
changed, duplicate entries would have been created.
parent 29ac9aea
...@@ -649,6 +649,17 @@ const char *announceSentinelAddr(const sentinelAddr *a) { ...@@ -649,6 +649,17 @@ const char *announceSentinelAddr(const sentinelAddr *a) {
return sentinel.announce_hostnames ? a->hostname : a->ip; return sentinel.announce_hostnames ? a->hostname : a->ip;
} }
/* Return an allocated sds with hostname/address:port. IPv6
* addresses are bracketed the same way anetFormatAddr() does.
*/
sds announceSentinelAddrAndPort(const sentinelAddr *a) {
const char *addr = announceSentinelAddr(a);
if (strchr(addr, ':') != NULL)
return sdscatprintf(sdsempty(), "[%s]:%d", addr, a->port);
else
return sdscatprintf(sdsempty(), "%s:%d", addr, a->port);
}
/* =========================== Events notification ========================== */ /* =========================== Events notification ========================== */
/* Send an event to log, pub/sub, user notification script. /* Send an event to log, pub/sub, user notification script.
...@@ -1273,7 +1284,7 @@ sentinelRedisInstance *createSentinelRedisInstance(char *name, int flags, char * ...@@ -1273,7 +1284,7 @@ sentinelRedisInstance *createSentinelRedisInstance(char *name, int flags, char *
sentinelRedisInstance *ri; sentinelRedisInstance *ri;
sentinelAddr *addr; sentinelAddr *addr;
dict *table = NULL; dict *table = NULL;
char slavename[NET_ADDR_STR_LEN], *sdsname; sds sdsname;
serverAssert(flags & (SRI_MASTER|SRI_SLAVE|SRI_SENTINEL)); serverAssert(flags & (SRI_MASTER|SRI_SLAVE|SRI_SENTINEL));
serverAssert((flags & SRI_MASTER) || master != NULL); serverAssert((flags & SRI_MASTER) || master != NULL);
...@@ -1282,11 +1293,11 @@ sentinelRedisInstance *createSentinelRedisInstance(char *name, int flags, char * ...@@ -1282,11 +1293,11 @@ sentinelRedisInstance *createSentinelRedisInstance(char *name, int flags, char *
addr = createSentinelAddr(hostname,port); addr = createSentinelAddr(hostname,port);
if (addr == NULL) return NULL; if (addr == NULL) return NULL;
/* For slaves use ip:port as name. */ /* For slaves use ip/host:port as name. */
if (flags & SRI_SLAVE) { if (flags & SRI_SLAVE)
anetFormatAddr(slavename, sizeof(slavename), addr->ip, port); sdsname = announceSentinelAddrAndPort(addr);
name = slavename; else
} sdsname = sdsnew(name);
/* Make sure the entry is not duplicated. This may happen when the same /* Make sure the entry is not duplicated. This may happen when the same
* name for a master is used multiple times inside the configuration or * name for a master is used multiple times inside the configuration or
...@@ -1295,7 +1306,6 @@ sentinelRedisInstance *createSentinelRedisInstance(char *name, int flags, char * ...@@ -1295,7 +1306,6 @@ sentinelRedisInstance *createSentinelRedisInstance(char *name, int flags, char *
if (flags & SRI_MASTER) table = sentinel.masters; if (flags & SRI_MASTER) table = sentinel.masters;
else if (flags & SRI_SLAVE) table = master->slaves; else if (flags & SRI_SLAVE) table = master->slaves;
else if (flags & SRI_SENTINEL) table = master->sentinels; else if (flags & SRI_SENTINEL) table = master->sentinels;
sdsname = sdsnew(name);
if (dictFind(table,sdsname)) { if (dictFind(table,sdsname)) {
releaseSentinelAddr(addr); releaseSentinelAddr(addr);
sdsfree(sdsname); sdsfree(sdsname);
...@@ -1399,7 +1409,6 @@ sentinelRedisInstance *sentinelRedisInstanceLookupSlave( ...@@ -1399,7 +1409,6 @@ sentinelRedisInstance *sentinelRedisInstanceLookupSlave(
{ {
sds key; sds key;
sentinelRedisInstance *slave; sentinelRedisInstance *slave;
char buf[NET_ADDR_STR_LEN];
sentinelAddr *addr; sentinelAddr *addr;
serverAssert(ri->flags & SRI_MASTER); serverAssert(ri->flags & SRI_MASTER);
...@@ -1410,11 +1419,9 @@ sentinelRedisInstance *sentinelRedisInstanceLookupSlave( ...@@ -1410,11 +1419,9 @@ sentinelRedisInstance *sentinelRedisInstanceLookupSlave(
*/ */
addr = createSentinelAddr(slave_addr, port); addr = createSentinelAddr(slave_addr, port);
if (!addr) return NULL; if (!addr) return NULL;
key = announceSentinelAddrAndPort(addr);
anetFormatAddr(buf,sizeof(buf),addr->ip,addr->port);
releaseSentinelAddr(addr); releaseSentinelAddr(addr);
key = sdsnew(buf);
slave = dictFetchValue(ri->slaves,key); slave = dictFetchValue(ri->slaves,key);
sdsfree(key); sdsfree(key);
return slave; return slave;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment