提交 8c1420ff 编写于 作者: A antirez

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
上级 a0573260
...@@ -559,6 +559,7 @@ void zunionInterGenericCommand(redisClient *c, robj *dstkey, int op) { ...@@ -559,6 +559,7 @@ void zunionInterGenericCommand(redisClient *c, robj *dstkey, int op) {
zset *dstzset; zset *dstzset;
dictIterator *di; dictIterator *di;
dictEntry *de; dictEntry *de;
int touched = 0;
/* expect setnum input keys to be given */ /* expect setnum input keys to be given */
setnum = atoi(c->argv[2]->ptr); setnum = atoi(c->argv[2]->ptr);
...@@ -703,12 +704,15 @@ void zunionInterGenericCommand(redisClient *c, robj *dstkey, int op) { ...@@ -703,12 +704,15 @@ void zunionInterGenericCommand(redisClient *c, robj *dstkey, int op) {
redisAssert(op == REDIS_OP_INTER || op == REDIS_OP_UNION); 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) { if (dstzset->zsl->length) {
dbAdd(c->db,dstkey,dstobj); dbAdd(c->db,dstkey,dstobj);
addReplyLongLong(c, dstzset->zsl->length); addReplyLongLong(c, dstzset->zsl->length);
touchWatchedKey(c->db,dstkey); if (!touched) touchWatchedKey(c->db,dstkey);
server.dirty++;
} else { } else {
decrRefCount(dstobj); decrRefCount(dstobj);
addReply(c, shared.czero); addReply(c, shared.czero);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册