diff --git a/src/rdb.c b/src/rdb.c index 6ce7871031..eaf7f8e022 100644 --- a/src/rdb.c +++ b/src/rdb.c @@ -1349,15 +1349,16 @@ ssize_t rdbSaveDb(rio *rdb, int dbid, int rdbflags, long *key_counter) { int curr_slot = kvstoreIteratorGetCurrentDictIndex(kvs_it); /* Save slot info. */ if (server.cluster_enabled && curr_slot != last_slot) { - if ((res = rdbSaveType(rdb, RDB_OPCODE_SLOT_INFO)) < 0) goto werr; - written += res; - if ((res = rdbSaveLen(rdb, curr_slot)) < 0) goto werr; - written += res; - if ((res = rdbSaveLen(rdb, kvstoreDictSize(db->keys, curr_slot))) < 0) goto werr; - written += res; - if ((res = rdbSaveLen(rdb, kvstoreDictSize(db->expires, curr_slot))) < 0) goto werr; - written += res; + sds slot_info = sdscatprintf(sdsempty(), "%i,%lu,%lu", + curr_slot, + kvstoreDictSize(db->keys, curr_slot), + kvstoreDictSize(db->expires, curr_slot)); + if ((res = rdbSaveAuxFieldStrStr(rdb, "slot-info", slot_info)) < 0) { + sdsfree(slot_info); + goto werr; + } last_slot = curr_slot; + sdsfree(slot_info); } sds keystr = dictGetKey(de); robj key, *o = dictGetVal(de); @@ -3078,20 +3079,6 @@ int rdbLoadRioWithLoadingCtx(rio *rdb, int rdbflags, rdbSaveInfo *rsi, rdbLoadin if ((expires_size = rdbLoadLen(rdb, NULL)) == RDB_LENERR) goto eoferr; should_expand_db = 1; continue; /* Read next opcode. */ - } else if (type == RDB_OPCODE_SLOT_INFO) { - uint64_t slot_id, slot_size, expires_slot_size; - if ((slot_id = rdbLoadLen(rdb, NULL)) == RDB_LENERR) goto eoferr; - if ((slot_size = rdbLoadLen(rdb, NULL)) == RDB_LENERR) goto eoferr; - if ((expires_slot_size = rdbLoadLen(rdb, NULL)) == RDB_LENERR) goto eoferr; - if (!server.cluster_enabled) { - continue; /* Ignore gracefully. */ - } - /* In cluster mode we resize individual slot specific dictionaries based on the number of keys that slot - * holds. */ - kvstoreDictExpand(db->keys, slot_id, slot_size); - kvstoreDictExpand(db->expires, slot_id, expires_slot_size); - should_expand_db = 0; - continue; /* Read next opcode. */ } else if (type == RDB_OPCODE_AUX) { /* AUX: generic string-string fields. Use to add state to RDB * which is backward compatible. Implementations of RDB loading @@ -3141,6 +3128,24 @@ int rdbLoadRioWithLoadingCtx(rio *rdb, int rdbflags, rdbSaveInfo *rsi, rdbLoadin if (isbase) serverLog(LL_NOTICE, "RDB is base AOF"); } else if (!strcasecmp(auxkey->ptr, "redis-bits")) { /* Just ignored. */ + } else if (!strcasecmp(auxkey->ptr, "slot-info")) { + int slot_id; + unsigned long slot_size, expires_slot_size; + /* Try to parse the slot information. in case the number of parsed arguments is smaller than expected + * Will fail the RDB load */ + if (sscanf(auxval->ptr, "%i,%lu,%lu", &slot_id, &slot_size, &expires_slot_size) < 3) { + decrRefCount(auxkey); + decrRefCount(auxval); + goto eoferr; + } + + if (server.cluster_enabled) { + /* In cluster mode we resize individual slot specific dictionaries based on the number of keys that slot + * holds. */ + kvstoreDictExpand(db->keys, slot_id, slot_size); + kvstoreDictExpand(db->expires, slot_id, expires_slot_size); + should_expand_db = 0; + } } else { /* Check if this is a dynamic aux field */ int handled = 0; diff --git a/src/rdb.h b/src/rdb.h index 393d2f658a..3b17cbe9de 100644 --- a/src/rdb.h +++ b/src/rdb.h @@ -38,7 +38,7 @@ /* The current RDB version. When the format changes in a way that is no longer * backward compatible this number gets incremented. */ -#define RDB_VERSION 12 +#define RDB_VERSION 11 /* Defines related to the dump file format. To store 32 bits lengths for short * keys requires a lot of space, so we check the most significant 2 bits of @@ -101,7 +101,6 @@ #define rdbIsObjectType(t) (((t) >= 0 && (t) <= 7) || ((t) >= 9 && (t) <= 21)) /* Special RDB opcodes (saved/loaded with rdbSaveType/rdbLoadType). */ -#define RDB_OPCODE_SLOT_INFO 244 /* Individual slot info, such as slot id and size (cluster mode only). */ #define RDB_OPCODE_FUNCTION2 245 /* function library data */ #define RDB_OPCODE_FUNCTION_PRE_GA 246 /* old function library data for 7.0 rc1 and rc2 */ #define RDB_OPCODE_MODULE_AUX 247 /* Module auxiliary data. */ diff --git a/src/valkey-check-rdb.c b/src/valkey-check-rdb.c index 7e93f70360..0b2fdbb666 100644 --- a/src/valkey-check-rdb.c +++ b/src/valkey-check-rdb.c @@ -256,12 +256,6 @@ int redis_check_rdb(char *rdbfilename, FILE *fp) { if ((db_size = rdbLoadLen(&rdb, NULL)) == RDB_LENERR) goto eoferr; if ((expires_size = rdbLoadLen(&rdb, NULL)) == RDB_LENERR) goto eoferr; continue; /* Read type again. */ - } else if (type == RDB_OPCODE_SLOT_INFO) { - uint64_t slot_id, slot_size, expires_slot_size; - if ((slot_id = rdbLoadLen(&rdb, NULL)) == RDB_LENERR) goto eoferr; - if ((slot_size = rdbLoadLen(&rdb, NULL)) == RDB_LENERR) goto eoferr; - if ((expires_slot_size = rdbLoadLen(&rdb, NULL)) == RDB_LENERR) goto eoferr; - continue; /* Read type again. */ } else if (type == RDB_OPCODE_AUX) { /* AUX: generic string-string fields. Use to add state to RDB * which is backward compatible. Implementations of RDB loading