Fix db->expires can't be defragged due to incorrect comparison in the expires stage (#14092)

This bug was introduced by https://github.com/redis/redis/issues/13814

When defragmenting `db->expires`, if the process exits early and
`db->expires` was modified in the meantime (e.g., FLUSHDB), we need to
check whether the previously defragmented expires is still the same as
the current one when resuming. If they differ, we should abort the
current defragmentation of expires.

However, in https://github.com/redis/redis/issues/13814, I made a
mistake by using `db->keys` and `db->expires`, as expires will never be
defragged.
This commit is contained in:
debing.sun 2025-06-05 21:52:33 +08:00 committed by GitHub
parent f646d2324b
commit 2467eff59a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 4 additions and 4 deletions

View file

@ -1241,7 +1241,7 @@ static doneStatus defragStageDbKeys(void *ctx, monotime endtime) {
static doneStatus defragStageExpiresKvstore(void *ctx, monotime endtime) {
defragKeysCtx *defrag_keys_ctx = ctx;
redisDb *db = &server.db[defrag_keys_ctx->dbid];
if (db->keys != defrag_keys_ctx->kvstate.kvs) {
if (db->expires != defrag_keys_ctx->kvstate.kvs) {
/* There has been a change of the kvs (flushdb, swapdb, etc.). Just complete the stage. */
return DEFRAG_DONE;
}

View file

@ -523,10 +523,10 @@ run_solo {defrag} {
r config set activedefrag no
wait_for_defrag_stop 500 100
r config resetstat
r config set active-defrag-threshold-lower 7
r config set active-defrag-threshold-lower 5
r config set active-defrag-cycle-min 65
r config set active-defrag-cycle-max 75
r config set active-defrag-ignore-bytes 1500kb
r config set active-defrag-ignore-bytes 1000kb
r config set maxmemory 0
r config set hash-max-listpack-value 512
r config set hash-max-listpack-entries 10
@ -597,7 +597,7 @@ run_solo {defrag} {
}
# wait for the active defrag to stop working
wait_for_defrag_stop 500 100 1.07
wait_for_defrag_stop 500 100 1.05
# test the fragmentation is lower
after 120 ;# serverCron only updates the info once in 100ms