diff options
author | Meir Shpilraien (Spielrein) <meir@redis.com> | 2022-10-16 08:30:01 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-16 08:30:01 +0300 |
commit | 56f97bfa5fb082f812c711676d5a77d29af56940 (patch) | |
tree | 24680f3c6b6a3ffb93d7d8c23d5c0e4399b16cf2 /src/cluster.c | |
parent | 871cc200a0046ccb73a67377327c6b97b52117a1 (diff) | |
download | redis-56f97bfa5fb082f812c711676d5a77d29af56940.tar.gz |
Fix wrong replication on cluster slotmap changes with module KSN propagation (#11377)
As discussed on #11084, `propagatePendingCommands` should happened after the del
notification is fired so that the notification effect and the `del` will be replicated inside MULTI EXEC.
Test was added to verify the fix.
Diffstat (limited to 'src/cluster.c')
-rw-r--r-- | src/cluster.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/src/cluster.c b/src/cluster.c index f7603611f..feb8f8d21 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -7092,6 +7092,10 @@ void slotToKeyDestroy(redisDb *db) { * The number of removed items is returned. */ unsigned int delKeysInSlot(unsigned int hashslot) { unsigned int j = 0; + + server.core_propagates = 1; + server.in_nested_call++; + dictEntry *de = (*server.db->slots_to_keys).by_slot[hashslot].head; while (de != NULL) { sds sdskey = dictGetKey(de); @@ -7099,13 +7103,17 @@ unsigned int delKeysInSlot(unsigned int hashslot) { robj *key = createStringObject(sdskey, sdslen(sdskey)); dbDelete(&server.db[0], key); propagateDeletion(&server.db[0], key, server.lazyfree_lazy_server_del); - propagatePendingCommands(); signalModifiedKey(NULL, &server.db[0], key); moduleNotifyKeyspaceEvent(NOTIFY_GENERIC, "del", key, server.db[0].id); decrRefCount(key); + propagatePendingCommands(); j++; server.dirty++; } + serverAssert(server.core_propagates); /* This function should not be re-entrant */ + + server.core_propagates = 0; + server.in_nested_call--; return j; } |