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().
This commit is contained in:
debing.sun 2025-03-19 10:22:47 +08:00 committed by GitHub
parent a5a3afd923
commit 26dcec4812
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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);
}