Unverified Commit f3bf8485 authored by Harkrishn Patro's avatar Harkrishn Patro Committed by GitHub
Browse files

Fix resize hash table dictionary iterator (#12660)

Dictionary iterator logic in the `tryResizeHashTables` method is picking the next
(incorrect) dictionary while the cursor is at a given slot. This could lead to some
dictionary/slot getting skipped from resizing.

Also stabilize the test.

problem introduced recently in #11695
parent 03345ddc
...@@ -608,8 +608,9 @@ void tryResizeHashTables(int dbid) { ...@@ -608,8 +608,9 @@ void tryResizeHashTables(int dbid) {
for (dbKeyType subdict = DB_MAIN; subdict <= DB_EXPIRES; subdict++) { for (dbKeyType subdict = DB_MAIN; subdict <= DB_EXPIRES; subdict++) {
dbIterator *dbit = dbIteratorInitFromSlot(db, subdict, db->sub_dict[subdict].resize_cursor); dbIterator *dbit = dbIteratorInitFromSlot(db, subdict, db->sub_dict[subdict].resize_cursor);
for (int i = 0; i < CRON_DBS_PER_CALL; i++) { for (int i = 0; i < CRON_DBS_PER_CALL; i++) {
dict *d = dbIteratorNextDict(dbit); dict *d = dbGetDictFromIterator(dbit);
slot = dbIteratorGetCurrentSlot(dbit); slot = dbIteratorGetCurrentSlot(dbit);
dbIteratorNextDict(dbit);
if (!d) break; if (!d) break;
if (htNeedsResize(d)) if (htNeedsResize(d))
dictResize(d); dictResize(d);
......
...@@ -2428,6 +2428,7 @@ typedef struct dbIterator dbIterator; ...@@ -2428,6 +2428,7 @@ typedef struct dbIterator dbIterator;
dbIterator *dbIteratorInit(redisDb *db, dbKeyType keyType); dbIterator *dbIteratorInit(redisDb *db, dbKeyType keyType);
dbIterator *dbIteratorInitFromSlot(redisDb *db, dbKeyType keyType, int slot); dbIterator *dbIteratorInitFromSlot(redisDb *db, dbKeyType keyType, int slot);
dict *dbIteratorNextDict(dbIterator *dbit); dict *dbIteratorNextDict(dbIterator *dbit);
dict *dbGetDictFromIterator(dbIterator *dbit);
int dbIteratorGetCurrentSlot(dbIterator *dbit); int dbIteratorGetCurrentSlot(dbIterator *dbit);
dictEntry *dbIteratorNext(dbIterator *iter); dictEntry *dbIteratorNext(dbIterator *iter);
......
...@@ -834,7 +834,7 @@ start_server {tags {"expire"}} { ...@@ -834,7 +834,7 @@ start_server {tags {"expire"}} {
} {} {needs:debug} } {} {needs:debug}
} }
start_cluster 1 0 {tags {"expire external:skip cluster"}} { start_cluster 1 0 {tags {"expire external:skip cluster slow"}} {
test "expire scan should skip dictionaries with lot's of empty buckets" { test "expire scan should skip dictionaries with lot's of empty buckets" {
# Collect two slots to help determine the expiry scan logic is able # Collect two slots to help determine the expiry scan logic is able
# to go past certain slots which aren't valid for scanning at the given point of time. # to go past certain slots which aren't valid for scanning at the given point of time.
...@@ -851,8 +851,6 @@ start_cluster 1 0 {tags {"expire external:skip cluster"}} { ...@@ -851,8 +851,6 @@ start_cluster 1 0 {tags {"expire external:skip cluster"}} {
# hashslot(key) is 12539 # hashslot(key) is 12539
r psetex key 500 val r psetex key 500 val
assert_equal 102 [r dbsize]
# disable resizing # disable resizing
r config set rdb-key-save-delay 10000000 r config set rdb-key-save-delay 10000000
r bgsave r bgsave
...@@ -882,23 +880,11 @@ start_cluster 1 0 {tags {"expire external:skip cluster"}} { ...@@ -882,23 +880,11 @@ start_cluster 1 0 {tags {"expire external:skip cluster"}} {
fail "bgsave did not stop in time." fail "bgsave did not stop in time."
} }
# Verify dict is under rehashing
set htstats [r debug HTSTATS 0]
assert_match {*rehashing target*} $htstats
# put some data into slot 12182 and trigger the resize # put some data into slot 12182 and trigger the resize
r psetex "{foo}0" 500 a r psetex "{foo}0" 500 a
# Verify dict rehashing has completed
set htstats [r debug HTSTATS 0]
wait_for_condition 20 100 {
![string match {*rehashing target*} $htstats]
} else {
fail "rehashing didn't complete"
}
# Verify all keys have expired # Verify all keys have expired
wait_for_condition 20 100 { wait_for_condition 200 100 {
[r dbsize] eq 0 [r dbsize] eq 0
} else { } else {
fail "Keys did not actively expire." fail "Keys did not actively expire."
......
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