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
This commit is contained in:
parent
03345ddc7f
commit
f3bf8485d8
@ -608,8 +608,9 @@ void tryResizeHashTables(int dbid) {
|
||||
for (dbKeyType subdict = DB_MAIN; subdict <= DB_EXPIRES; subdict++) {
|
||||
dbIterator *dbit = dbIteratorInitFromSlot(db, subdict, db->sub_dict[subdict].resize_cursor);
|
||||
for (int i = 0; i < CRON_DBS_PER_CALL; i++) {
|
||||
dict *d = dbIteratorNextDict(dbit);
|
||||
dict *d = dbGetDictFromIterator(dbit);
|
||||
slot = dbIteratorGetCurrentSlot(dbit);
|
||||
dbIteratorNextDict(dbit);
|
||||
if (!d) break;
|
||||
if (htNeedsResize(d))
|
||||
dictResize(d);
|
||||
|
@ -2428,6 +2428,7 @@ typedef struct dbIterator dbIterator;
|
||||
dbIterator *dbIteratorInit(redisDb *db, dbKeyType keyType);
|
||||
dbIterator *dbIteratorInitFromSlot(redisDb *db, dbKeyType keyType, int slot);
|
||||
dict *dbIteratorNextDict(dbIterator *dbit);
|
||||
dict *dbGetDictFromIterator(dbIterator *dbit);
|
||||
int dbIteratorGetCurrentSlot(dbIterator *dbit);
|
||||
dictEntry *dbIteratorNext(dbIterator *iter);
|
||||
|
||||
|
@ -834,7 +834,7 @@ start_server {tags {"expire"}} {
|
||||
} {} {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" {
|
||||
# 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.
|
||||
@ -851,8 +851,6 @@ start_cluster 1 0 {tags {"expire external:skip cluster"}} {
|
||||
# hashslot(key) is 12539
|
||||
r psetex key 500 val
|
||||
|
||||
assert_equal 102 [r dbsize]
|
||||
|
||||
# disable resizing
|
||||
r config set rdb-key-save-delay 10000000
|
||||
r bgsave
|
||||
@ -882,23 +880,11 @@ start_cluster 1 0 {tags {"expire external:skip cluster"}} {
|
||||
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
|
||||
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
|
||||
wait_for_condition 20 100 {
|
||||
wait_for_condition 200 100 {
|
||||
[r dbsize] eq 0
|
||||
} else {
|
||||
fail "Keys did not actively expire."
|
||||
|
Loading…
x
Reference in New Issue
Block a user