Blocking clients should not crash if an active replica loads a remote RDB with a key in the blocklist
Former-commit-id: 1c525e20b10e0a47af687a0d46faf75229a1cbf5
This commit is contained in:
parent
da2a3dbf99
commit
e8753d1b4b
@ -672,6 +672,13 @@ void signalKeyAsReady(redisDb *db, robj *key) {
|
|||||||
/* Key was already signaled? No need to queue it again. */
|
/* Key was already signaled? No need to queue it again. */
|
||||||
if (dictFind(db->ready_keys,key) != NULL) return;
|
if (dictFind(db->ready_keys,key) != NULL) return;
|
||||||
|
|
||||||
|
if (key->getrefcount() == OBJ_STATIC_REFCOUNT) {
|
||||||
|
// Sometimes a key may be stack allocated, we'll need to dupe it
|
||||||
|
robj *newKey = createStringObject(szFromObj(key), sdslen(szFromObj(key)));
|
||||||
|
newKey->setrefcount(0); // Start with 0 but don't free
|
||||||
|
key = newKey;
|
||||||
|
}
|
||||||
|
|
||||||
/* Ok, we need to queue this key into g_pserver->ready_keys. */
|
/* Ok, we need to queue this key into g_pserver->ready_keys. */
|
||||||
rl = (readyList*)zmalloc(sizeof(*rl), MALLOC_SHARED);
|
rl = (readyList*)zmalloc(sizeof(*rl), MALLOC_SHARED);
|
||||||
rl->key = key;
|
rl->key = key;
|
||||||
|
@ -3049,7 +3049,8 @@ struct redisMaster *replicationAddMaster(char *ip, int port) {
|
|||||||
else
|
else
|
||||||
freeClientAsync(mi->master);
|
freeClientAsync(mi->master);
|
||||||
}
|
}
|
||||||
disconnectAllBlockedClients(); /* Clients blocked in master, now replica. */
|
if (!g_pserver->fActiveReplica)
|
||||||
|
disconnectAllBlockedClients(); /* Clients blocked in master, now replica. */
|
||||||
|
|
||||||
/* Update oom_score_adj */
|
/* Update oom_score_adj */
|
||||||
setOOMScoreAdj(-1);
|
setOOMScoreAdj(-1);
|
||||||
|
@ -247,6 +247,23 @@ start_server {tags {"active-repl"} overrides {active-replica yes}} {
|
|||||||
assert_equal {bar} [$master get testkey] {master is correct}
|
assert_equal {bar} [$master get testkey] {master is correct}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test {Active replica merge works with client blocked} {
|
||||||
|
$slave flushall
|
||||||
|
$slave replicaof no one
|
||||||
|
$master replicaof no one
|
||||||
|
after 100
|
||||||
|
set rd [redis_deferring_client]
|
||||||
|
$rd blpop testlist 0
|
||||||
|
$slave lpush testlist foo
|
||||||
|
|
||||||
|
#OK Now reconnect
|
||||||
|
$slave replicaof $master_host $master_port
|
||||||
|
$master replicaof $slave_host $slave_port
|
||||||
|
after 1000
|
||||||
|
|
||||||
|
$rd read
|
||||||
|
} {testlist foo}
|
||||||
|
|
||||||
test {Active replica different databases} {
|
test {Active replica different databases} {
|
||||||
$master select 3
|
$master select 3
|
||||||
$master set testkey abcd
|
$master set testkey abcd
|
||||||
|
Loading…
x
Reference in New Issue
Block a user