From 26dcec4812ecddcf4111ac031f57f544b0ca6987 Mon Sep 17 00:00:00 2001 From: "debing.sun" Date: Wed, 19 Mar 2025 10:22:47 +0800 Subject: [PATCH] Fix messed-up unblocked clients in flush command (#13865) Fix https://github.com/redis/redis/pull/13853#pullrequestreview-2675227138 This PR ensures that the client's current command is not reset by unblockClient(), while still needing to be handled after `unblockclient()`. The FLUSH command still requires reprocessing (update the replication offset) after unblockClient(). Therefore, we mark such blocked clients with the CLIENT_PENDING_COMMAND flag to prevent the command from being reset during unblockClient(). --- src/db.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/db.c b/src/db.c index cf31df4e1..63b561d84 100644 --- a/src/db.c +++ b/src/db.c @@ -834,8 +834,13 @@ void flushallSyncBgDone(uint64_t client_id, void *sflush) { /* mark client as unblocked */ unblockClient(c, 1); - /* FLUSH command is finished. resetClient() and update replication offset. */ - commandProcessed(c); + if (c->flags & CLIENT_PENDING_COMMAND) { + c->flags &= ~CLIENT_PENDING_COMMAND; + /* The FLUSH command won't be reprocessed, FLUSH command is finished, but + * we still need to complete its full processing flow, including updating + * the replication offset. */ + commandProcessed(c); + } /* On flush completion, update the client's memory */ updateClientMemUsageAndBucket(c); @@ -880,6 +885,10 @@ int flushCommandCommon(client *c, int type, int flags, SlotsFlush *sflush) { elapsedStart(&c->bstate.lazyfreeStartTime); c->bstate.timeout = 0; + /* We still need to perform cleanup operations for the command, including + * updating the replication offset, so mark this command as pending to + * avoid command from being reset during unblock. */ + c->flags |= CLIENT_PENDING_COMMAND; blockClient(c,BLOCKED_LAZYFREE); bioCreateCompRq(BIO_WORKER_LAZY_FREE, flushallSyncBgDone, c->id, sflush); }