提交 9b30e1a2 编写于 作者: A antirez

WATCH is now able to detect keys removed by FLUSHALL and FLUSHDB

上级 c20c189d
......@@ -637,6 +637,7 @@ static int rewriteAppendOnlyFileBackground(void);
static int vmSwapObjectBlocking(robj *key, robj *val);
static int prepareForShutdown();
static void touchWatchedKey(redisDb *db, robj *key);
static void touchWatchedKeysOnFlush(int dbid);
static void unwatchAllKeys(redisClient *c);
static void authCommand(redisClient *c);
......@@ -6780,12 +6781,14 @@ static void convertToRealHash(robj *o) {
static void flushdbCommand(redisClient *c) {
server.dirty += dictSize(c->db->dict);
touchWatchedKeysOnFlush(c->db->id);
dictEmpty(c->db->dict);
dictEmpty(c->db->expires);
addReply(c,shared.ok);
}
static void flushallCommand(redisClient *c) {
touchWatchedKeysOnFlush(-1);
server.dirty += emptyDb();
addReply(c,shared.ok);
if (server.bgsavechildpid != -1) {
......@@ -10475,6 +10478,33 @@ static void touchWatchedKey(redisDb *db, robj *key) {
}
}
/* On FLUSHDB or FLUSHALL all the watched keys that are present before the
* flush but will be deleted as effect of the flushing operation should
* be touched. "dbid" is the DB that's getting the flush. -1 if it is
* a FLUSHALL operation (all the DBs flushed). */
static void touchWatchedKeysOnFlush(int dbid) {
listIter li1, li2;
listNode *ln;
/* For every client, check all the waited keys */
listRewind(server.clients,&li1);
while((ln = listNext(&li1))) {
redisClient *c = listNodeValue(ln);
listRewind(c->watched_keys,&li2);
while((ln = listNext(&li2))) {
watchedKey *wk = listNodeValue(ln);
/* For every watched key matching the specified DB, if the
* key exists, mark the client as dirty, as the key will be
* removed. */
if (dbid == -1 || wk->db->id == dbid) {
if (dictFind(wk->db->dict, wk->key) != NULL)
c->flags |= REDIS_DIRTY_CAS;
}
}
}
}
static void watchCommand(redisClient *c) {
int j;
......
......@@ -15,6 +15,7 @@ proc test {name code okpattern} {
puts $warnings
}
}
puts "Script died with $error"
exit 1
}
if {$okpattern eq $retval || [string match $okpattern $retval]} {
......
......@@ -63,4 +63,52 @@ start_server default.conf {} {
test {UNWATCH when there is nothing watched works as expected} {
r unwatch
} {OK}
test {FLUSHALL is able to touch the watched keys} {
r set x 30
r watch x
r flushall
r multi
r ping
r exec
} {}
test {FLUSHALL does not touch non affected keys} {
r del x
r watch x
r flushall
r multi
r ping
r exec
} {PONG}
test {FLUSHDB is able to touch the watched keys} {
r set x 30
r watch x
r flushdb
r multi
r ping
r exec
} {}
test {FLUSHDB does not touch non affected keys} {
r del x
r watch x
r flushdb
r multi
r ping
r exec
} {PONG}
test {WATCH is able to remember the DB a key belongs to} {
r select 5
r set x 30
r watch x
r select 1
r set x 10
r select 5
r multi
r ping
r exec
} {PONG}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册