From dd97d597448a1c8158dc96826466cd46ba1bc135 Mon Sep 17 00:00:00 2001 From: Henry Filgueiras <33638747+henry-filgueiras@users.noreply.github.com> Date: Mon, 20 Apr 2026 15:56:28 -0700 Subject: [PATCH] Disarm dict-rehash timing unconditionally at top-level call() exit The disarm of dictRehashStepTiming was inside the if (update_command_stats) block, which is skipped during AOF loading and other contexts where command stats are suppressed. Across those paths the flag stayed armed, so every incremental rehash step continued to pay the getMonotonicUs() cost and wrote into the accumulator that was never read back. The arm/disarm pair is state-machine cleanup, not a stats emission. Move the disarm out of the stats block, guarded only by execution_nesting == 0, so it runs on every outermost call() exit. Emission remains where it was: inside the stats block, adjacent to durationAddSample. Restores the "zero-cost when latency monitoring is disabled" invariant on all code paths through call(), including AOF replay. --- src/server.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/server.c b/src/server.c index e3c122966..06a10334c 100644 --- a/src/server.c +++ b/src/server.c @@ -4020,14 +4020,16 @@ void call(client *c, int flags) { durationAddSample(EL_DURATION_TYPE_CMD, duration); latencyAddSampleIfNeeded("dict-rehash-during-command", (long long)(dictRehashStepElapsedUs/1000)); - /* Disarm the dict-rehash timing path between top-level calls so - * any rehash work done in cron (e.g. via active expire) does not - * pay the timing cost. The accumulator is zeroed again at the - * next top-level entry. */ - dictRehashStepTiming = 0; } } + /* Disarm the dict-rehash timing path unconditionally at outermost call() + * exit, so cron work between commands does not pay the timing cost. This + * must run regardless of update_command_stats (e.g. during AOF loading) + * so the flag cannot stay armed across paths that skip the stats block. */ + if (server.execution_nesting == 0) + dictRehashStepTiming = 0; + /* Log the command into the Slow log if needed. * If the client is blocked we will handle slowlog when it is unblocked. */ if (update_command_stats && !(c->flags & CLIENT_BLOCKED))