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. */
|
||||
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. */
|
||||
rl = (readyList*)zmalloc(sizeof(*rl), MALLOC_SHARED);
|
||||
rl->key = key;
|
||||
|
@ -3049,6 +3049,7 @@ struct redisMaster *replicationAddMaster(char *ip, int port) {
|
||||
else
|
||||
freeClientAsync(mi->master);
|
||||
}
|
||||
if (!g_pserver->fActiveReplica)
|
||||
disconnectAllBlockedClients(); /* Clients blocked in master, now replica. */
|
||||
|
||||
/* Update oom_score_adj */
|
||||
|
@ -247,6 +247,23 @@ start_server {tags {"active-repl"} overrides {active-replica yes}} {
|
||||
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} {
|
||||
$master select 3
|
||||
$master set testkey abcd
|
||||
|
Loading…
x
Reference in New Issue
Block a user