From 99c807bd43a092627d2811306d56c474c88c9701 Mon Sep 17 00:00:00 2001 From: Josh Hershberg Date: Wed, 26 Mar 2025 14:28:49 +0200 Subject: [PATCH] RDB: Filter keys in unowned slots This PR excludes unowned slots while writing an RDB. This PR is a preperation for future work to do with resharding. In addition, a "debug set key value" command is added to fascilitate testing of this feature. Signed-off-by: Josh Hershberg --- src/debug.c | 5 +++++ src/kvstore.c | 5 +++++ src/kvstore.h | 1 + src/rdb.c | 14 ++++++++++++++ 4 files changed, 25 insertions(+) diff --git a/src/debug.c b/src/debug.c index 5584ae387..f7c61256b 100644 --- a/src/debug.c +++ b/src/debug.c @@ -496,6 +496,8 @@ void debugCommand(client *c) { " Output SHA and content of all scripts or of a specific script with its SHA.", "MARK-INTERNAL-CLIENT [UNMARK]", " Promote the current connection to an internal connection.", +"SET key value", +" Set a key, even if it is in a slot not owned by this node.", NULL }; addExtendedReplyHelp(c, help, clusterDebugCommandExtendedHelp()); @@ -1087,6 +1089,9 @@ NULL addReplySubcommandSyntaxError(c); return; } + } else if (!strcasecmp(c->argv[1]->ptr, "set") && c->argc == 4) { + setKey(c,c->db, c->argv[2], c->argv[3], SETKEY_ADD_OR_UPDATE); + addReply(c, shared.ok); } else if(!handleDebugClusterCommand(c)) { addReplySubcommandSyntaxError(c); return; diff --git a/src/kvstore.c b/src/kvstore.c index d7948c9ab..ac87c7903 100644 --- a/src/kvstore.c +++ b/src/kvstore.c @@ -654,6 +654,11 @@ dictEntry *kvstoreIteratorNext(kvstoreIterator *kvs_it) { return de; } +void kvstoreSkipToNextDict(kvstoreIterator *kvs_it) { + dict *d = kvstoreIteratorNextDict(kvs_it); + if (d) dictInitSafeIterator(&kvs_it->di, d); +} + /* This method traverses through kvstore dictionaries and triggers a resize. * It first tries to shrink if needed, and if it isn't, it tries to expand. */ void kvstoreTryResizeDicts(kvstore *kvs, int limit) { diff --git a/src/kvstore.h b/src/kvstore.h index c077dd625..ee57e5232 100644 --- a/src/kvstore.h +++ b/src/kvstore.h @@ -68,6 +68,7 @@ uint64_t kvstoreGetHash(kvstore *kvs, const void *key); kvstoreIterator *kvstoreIteratorInit(kvstore *kvs); void kvstoreIteratorRelease(kvstoreIterator *kvs_it); dict *kvstoreIteratorNextDict(kvstoreIterator *kvs_it); +void kvstoreSkipToNextDict(kvstoreIterator *kvs_it); int kvstoreIteratorGetCurrentDictIndex(kvstoreIterator *kvs_it); dictEntry *kvstoreIteratorNext(kvstoreIterator *kvs_it); diff --git a/src/rdb.c b/src/rdb.c index 7a072cad5..e1e0e1251 100644 --- a/src/rdb.c +++ b/src/rdb.c @@ -20,6 +20,7 @@ #include "functions.h" #include "intset.h" /* Compact integer set structure */ #include "bio.h" +#include "cluster.h" #include #include @@ -1396,9 +1397,22 @@ ssize_t rdbSaveDb(rio *rdb, int dbid, int rdbflags, long *key_counter) { kvs_it = kvstoreIteratorInit(db->keys); int last_slot = -1; + clusterNode *myNode = NULL; + if (server.cluster_enabled) { + myNode = getMyClusterNode(); + if (NULL == myNode) { + goto werr; + } + } /* Iterate this DB writing every entry */ while ((de = kvstoreIteratorNext(kvs_it)) != NULL) { int curr_slot = kvstoreIteratorGetCurrentDictIndex(kvs_it); + if (server.cluster_enabled) { + if (getNodeBySlot(curr_slot) != myNode) { + kvstoreSkipToNextDict(kvs_it); + continue; + } + } /* Save slot info. */ if (server.cluster_enabled && curr_slot != last_slot) { if ((res = rdbSaveType(rdb, RDB_OPCODE_SLOT_INFO)) < 0) goto werr;