Remove assert and refuse delete expired on ro replicas (#10248)

There's an assertion added recently to make sure that non-write commands don't use lookupKeyWrite,
It was initially meant to be used only on read-only replicas, but we thought it'll not have enough coverage,
so used it on the masters too.
We now realize that in some cases this can cause issues for modules, so we remove the assert.

Other than that, we also make sure not to force expireIfNeeded on read-only replicas.
even if they somehow run a write command.

See https://github.com/redis/redis/pull/9572#discussion_r800179373
This commit is contained in:
Viktor Söderqvist 2022-02-08 12:19:27 +01:00 committed by GitHub
parent 2e1bc942aa
commit b571c9609d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -83,16 +83,16 @@ robj *lookupKey(redisDb *db, robj *key, int flags) {
robj *val = NULL;
if (de) {
val = dictGetVal(de);
int force_delete_expired = flags & LOOKUP_WRITE;
if (force_delete_expired) {
/* Forcing deletion of expired keys on a replica makes the replica
* inconsistent with the master. The reason it's allowed for write
* commands is to make writable replicas behave consistently. It
* shall not be used in readonly commands. Modules are accepted so
* that we don't break old modules. */
client *c = server.in_script ? scriptGetClient() : server.current_client;
serverAssert(!c || !c->cmd || (c->cmd->flags & (CMD_WRITE|CMD_MODULE)));
}
/* Forcing deletion of expired keys on a replica makes the replica
* inconsistent with the master. We forbid it on readonly replicas, but
* we have to allow it on writable replicas to make write commands
* behave consistently.
*
* It's possible that the WRITE flag is set even during a readonly
* command, since the command may trigger events that cause modules to
* perform additional writes. */
int is_ro_replica = server.masterhost && server.repl_slave_ro;
int force_delete_expired = flags & LOOKUP_WRITE && !is_ro_replica;
if (expireIfNeeded(db, key, force_delete_expired)) {
/* The key is no longer valid. */
val = NULL;