diff --git a/src/server.c b/src/server.c index f49c1f76..9f9829f8 100644 --- a/src/server.c +++ b/src/server.c @@ -2157,6 +2157,16 @@ void preventCommandPropagation(client *c) { c->flags |= CLIENT_PREVENT_PROP; } +/* AOF specific version of preventCommandPropagation(). */ +void preventCommandAOF(client *c) { + c->flags |= CLIENT_PREVENT_AOF_PROP; +} + +/* Replication specific version of preventCommandPropagation(). */ +void preventCommandReplication(client *c) { + c->flags |= CLIENT_PREVENT_REPL_PROP; +} + /* Call() is the core of Redis execution of a command */ void call(client *c, int flags) { long long dirty, start, duration; @@ -2216,10 +2226,24 @@ void call(client *c, int flags) { if (flags & CMD_CALL_PROPAGATE && (c->flags & CLIENT_PREVENT_PROP) == 0) { int flags = PROPAGATE_NONE; - if (c->flags & CLIENT_FORCE_REPL) flags |= PROPAGATE_REPL; - if (c->flags & CLIENT_FORCE_AOF) flags |= PROPAGATE_AOF; + /* Check if the command operated changes in the data set. If so + * set for replication / AOF propagation. */ if (dirty) flags |= (PROPAGATE_REPL | PROPAGATE_AOF); + + /* If the command forced AOF / replication of the command, set + * the flags regardless of the command effects on the data set. */ + if (c->flags & CLIENT_FORCE_REPL) flags |= PROPAGATE_REPL; + if (c->flags & CLIENT_FORCE_AOF) flags |= PROPAGATE_AOF; + + /* However calls to preventCommandPropagation() or its selective + * variants preventCommandAOF() and preventCommandReplicaiton() + * will clear the flags to avoid propagation. */ + if (c->flags & CLIENT_PREVENT_REPL_PROP) flags &= ~PROPAGATE_REPL; + if (c->flags & CLIENT_PREVENT_AOF_PROP) flags &= ~PROPAGATE_AOF; + + /* Call propagate() only if at least one of AOF / replication + * propagation is needed. */ if (flags != PROPAGATE_NONE) propagate(c->cmd,c->db->id,c->argv,c->argc,flags); } diff --git a/src/server.h b/src/server.h index 3c159847..4f84e7da 100644 --- a/src/server.h +++ b/src/server.h @@ -242,12 +242,14 @@ typedef long long mstime_t; /* millisecond time type. */ #define CLIENT_PRE_PSYNC (1<<16) /* Instance don't understand PSYNC. */ #define CLIENT_READONLY (1<<17) /* Cluster client is in read-only state. */ #define CLIENT_PUBSUB (1<<18) /* Client is in Pub/Sub mode. */ -#define CLIENT_PREVENT_PROP (1<<19) /* Don't propagate to AOF / Slaves. */ -#define CLIENT_PENDING_WRITE (1<<20) /* Client has output to send but a write +#define CLIENT_PREVENT_AOF_PROP (1<<19) /* Don't propagate to AOF. */ +#define CLIENT_PREVENT_REPL_PROP (1<<20) /* Don't propagate to slaves. */ +#define CLIENT_PREVENT_PROP (CLIENT_PREVENT_AOF_PROP|CLIENT_PREVENT_REPL_PROP) +#define CLIENT_PENDING_WRITE (1<<21) /* Client has output to send but a write handler is yet not installed. */ -#define CLIENT_REPLY_OFF (1<<21) /* Don't send replies to client. */ -#define CLIENT_REPLY_SKIP_NEXT (1<<22) /* Set CLIENT_REPLY_SKIP for next cmd */ -#define CLIENT_REPLY_SKIP (1<<23) /* Don't send just this reply. */ +#define CLIENT_REPLY_OFF (1<<22) /* Don't send replies to client. */ +#define CLIENT_REPLY_SKIP_NEXT (1<<23) /* Set CLIENT_REPLY_SKIP for next cmd */ +#define CLIENT_REPLY_SKIP (1<<24) /* Don't send just this reply. */ /* Client block type (btype field in client structure) * if CLIENT_BLOCKED flag is set. */ @@ -1306,6 +1308,8 @@ void propagate(struct redisCommand *cmd, int dbid, robj **argv, int argc, int fl void alsoPropagate(struct redisCommand *cmd, int dbid, robj **argv, int argc, int target); void forceCommandPropagation(client *c, int flags); void preventCommandPropagation(client *c); +void preventCommandAOF(client *c); +void preventCommandReplication(client *c); int prepareForShutdown(); #ifdef __GNUC__ void serverLog(int level, const char *fmt, ...)