Skip to content

Commit 7ed808d

Browse files
committed
fix(rdb): Fix RDB load bug when loading hset
1 parent d3c848f commit 7ed808d

File tree

3 files changed

+33
-22
lines changed

3 files changed

+33
-22
lines changed

src/redis/zmalloc_mi.c

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ size_t zmalloc_usable_size(const void* p) {
3737
void zfree(void* ptr) {
3838
size_t usable = mi_usable_size(ptr);
3939

40-
// I wish we can keep this assert but rdb_load creates objects in one thread and
41-
// uses them in another.
4240
// assert(zmalloc_used_memory_tl >= (ssize_t)usable);
4341
zmalloc_used_memory_tl -= usable;
4442

@@ -51,34 +49,34 @@ void* zrealloc(void* ptr, size_t size) {
5149
}
5250

5351
void* zcalloc(size_t size) {
54-
size_t usable = mi_good_size(size);
52+
// mi_good_size(size) is not working. try for example, size=690557.
5553

54+
void* res = mi_heap_calloc(zmalloc_heap, 1, size);
55+
size_t usable = mi_usable_size(res);
5656
zmalloc_used_memory_tl += usable;
5757

58-
return mi_heap_calloc(zmalloc_heap, 1, size);
58+
return res;
5959
}
6060

6161
void* zmalloc_usable(size_t size, size_t* usable) {
62-
size_t g = mi_good_size(size);
63-
*usable = g;
64-
65-
zmalloc_used_memory_tl += g;
6662
assert(zmalloc_heap);
67-
void* ptr = mi_heap_malloc(zmalloc_heap, g);
68-
assert(mi_usable_size(ptr) == g);
63+
void* res = mi_heap_malloc(zmalloc_heap, size);
64+
size_t uss = mi_usable_size(res);
65+
*usable = uss;
6966

70-
return ptr;
67+
zmalloc_used_memory_tl += uss;
68+
69+
return res;
7170
}
7271

7372
void* zrealloc_usable(void* ptr, size_t size, size_t* usable) {
74-
size_t g = mi_good_size(size);
75-
size_t prev = mi_usable_size(ptr);
76-
*usable = g;
73+
ssize_t prev = mi_usable_size(ptr);
74+
75+
void* res = mi_heap_realloc(zmalloc_heap, ptr, size);
76+
ssize_t uss = mi_usable_size(res);
77+
*usable = uss;
78+
zmalloc_used_memory_tl += (uss - prev);
7779

78-
zmalloc_used_memory_tl += (g - prev);
79-
void* res = mi_heap_realloc(zmalloc_heap, ptr, g);
80-
// does not hold, say when prev = 16 and size = 6. mi_malloc does not shrink in this case.
81-
// assert(mi_usable_size(res) == g);
8280
return res;
8381
}
8482

@@ -87,8 +85,9 @@ size_t znallocx(size_t size) {
8785
}
8886

8987
void zfree_size(void* ptr, size_t size) {
90-
zmalloc_used_memory_tl -= size;
91-
mi_free_size(ptr, size);
88+
ssize_t uss = mi_usable_size(ptr);
89+
zmalloc_used_memory_tl -= uss;
90+
mi_free_size(ptr, uss);
9291
}
9392

9493
void* ztrymalloc(size_t size) {

src/server/rdb_load.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,8 @@ void RdbLoader::OpaqueObjLoader::CreateHMap(const LoadTrace* ltrace) {
395395
}
396396

397397
lp = lpShrinkToFit(lp);
398-
robj* o = createObject(OBJ_HASH, lp);
399-
o->encoding = OBJ_ENCODING_LISTPACK;
398+
res = createObject(OBJ_HASH, lp);
399+
res->encoding = OBJ_ENCODING_LISTPACK;
400400
} else {
401401
dict* hmap = dictCreate(&hashDictType);
402402

src/server/rdb_test.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
extern "C" {
77
#include "redis/crc64.h"
8+
#include "redis/redis_aux.h"
89
#include "redis/zmalloc.h"
910
}
1011

@@ -257,4 +258,15 @@ TEST_F(RdbTest, SaveManyDbs) {
257258
}
258259
}
259260

261+
TEST_F(RdbTest, HMapBugs) {
262+
// Force OBJ_ENCODING_HT encoding.
263+
server.hash_max_listpack_value = 0;
264+
Run({"hset", "hmap1", "key1", "val", "key2", "val2"});
265+
Run({"hset", "hmap2", "key1", string(690557, 'a')});
266+
267+
server.hash_max_listpack_value = 32;
268+
Run({"debug", "reload"});
269+
EXPECT_EQ(2, CheckedInt({"hlen", "hmap1"}));
270+
}
271+
260272
} // namespace dfly

0 commit comments

Comments
 (0)