From 8c1420ff2a2a9e68ab3faa98bb82d682301fa66b Mon Sep 17 00:00:00 2001 From: antirez Date: Wed, 28 Jul 2010 18:42:02 +0200 Subject: [PATCH] Fixed a replication bug in ZINTERSTORE. In order to trigger the bug what's needed is to call ZINTERSTORE resulting into an empty set created, bug against a key that already existed. The command was not propagated, so the replica ended with the key that the master removed. Sequence of command to reproduce: redis-cli hset 446 34 905 redis-cli hset 446 393 911 redis-cli zadd 966 0.085412045980529885 652 redis-cli zadd 645 0.25081839284432045 280 redis-cli zinterstore 446 2 966 645 --- src/t_zset.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/t_zset.c b/src/t_zset.c index 0fcd6ea3..9b59ca9a 100644 --- a/src/t_zset.c +++ b/src/t_zset.c @@ -559,6 +559,7 @@ void zunionInterGenericCommand(redisClient *c, robj *dstkey, int op) { zset *dstzset; dictIterator *di; dictEntry *de; + int touched = 0; /* expect setnum input keys to be given */ setnum = atoi(c->argv[2]->ptr); @@ -703,12 +704,15 @@ void zunionInterGenericCommand(redisClient *c, robj *dstkey, int op) { redisAssert(op == REDIS_OP_INTER || op == REDIS_OP_UNION); } - dbDelete(c->db,dstkey); + if (dbDelete(c->db,dstkey)) { + touchWatchedKey(c->db,dstkey); + touched = 1; + server.dirty++; + } if (dstzset->zsl->length) { dbAdd(c->db,dstkey,dstobj); addReplyLongLong(c, dstzset->zsl->length); - touchWatchedKey(c->db,dstkey); - server.dirty++; + if (!touched) touchWatchedKey(c->db,dstkey); } else { decrRefCount(dstobj); addReply(c, shared.czero); -- 2.45.2