From 2467eff59ab1b079de6dc24226c7bfc81e444338 Mon Sep 17 00:00:00 2001 From: "debing.sun" Date: Thu, 5 Jun 2025 21:52:33 +0800 Subject: [PATCH] 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. --- src/defrag.c | 2 +- tests/unit/memefficiency.tcl | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/defrag.c b/src/defrag.c index 6cc100aef0..44f19f18ed 100644 --- a/src/defrag.c +++ b/src/defrag.c @@ -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; } diff --git a/tests/unit/memefficiency.tcl b/tests/unit/memefficiency.tcl index 88ccf25122..e192355b22 100644 --- a/tests/unit/memefficiency.tcl +++ b/tests/unit/memefficiency.tcl @@ -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