free client's multi state when it becomes dirty (#961)

Release the client's MULTI state when the transaction becomes dirty to
save memory.

---------

Signed-off-by: zhaozhao.zz <zhaozhao.zz@alibaba-inc.com>
This commit is contained in:
zhaozhao.zz 2024-08-29 19:20:53 +08:00 committed by GitHub
parent ad0ede302c
commit 4a9b4f667c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -55,6 +55,13 @@ void freeClientMultiState(client *c) {
zfree(c->mstate.commands);
}
void resetClientMultiState(client *c) {
if (c->mstate.commands) {
freeClientMultiState(c);
initClientMultiState(c);
}
}
/* Add a new command into the MULTI commands queue */
void queueMultiCommand(client *c, uint64_t cmd_flags) {
multiCmd *mc;
@ -94,8 +101,7 @@ void queueMultiCommand(client *c, uint64_t cmd_flags) {
}
void discardTransaction(client *c) {
freeClientMultiState(c);
initClientMultiState(c);
resetClientMultiState(c);
c->flag.multi = 0;
c->flag.dirty_cas = 0;
c->flag.dirty_exec = 0;
@ -105,7 +111,10 @@ void discardTransaction(client *c) {
/* Flag the transaction as DIRTY_EXEC so that EXEC will fail.
* Should be called every time there is an error while queueing a command. */
void flagTransaction(client *c) {
if (c->flag.multi) c->flag.dirty_exec = 1;
if (c->flag.multi) {
c->flag.dirty_exec = 1;
resetClientMultiState(c);
}
}
void multiCommand(client *c) {
@ -391,6 +400,7 @@ void touchWatchedKey(serverDb *db, robj *key) {
}
c->flag.dirty_cas = 1;
resetClientMultiState(c);
/* As the client is marked as dirty, there is no point in getting here
* again in case that key (or others) are modified again (or keep the
* memory overhead till EXEC). */
@ -442,6 +452,7 @@ void touchAllWatchedKeysInDb(serverDb *emptied, serverDb *replaced_with) {
}
client *c = wk->client;
c->flag.dirty_cas = 1;
resetClientMultiState(c);
/* Note - we could potentially call unwatchAllKeys for this specific client in order to reduce
* the total number of iterations. BUT this could also free the current next entry pointer
* held by the iterator and can lead to use-after-free. */