Hide empty and loading replicas from CLUSTER SLOTS responses (#9287)
Hide empty and loading replicas from CLUSTER SLOTS responses
This commit is contained in:
parent
2391aefd82
commit
d98d1ad574
@ -4417,6 +4417,24 @@ int getSlotOrReply(client *c, robj *o) {
|
|||||||
return (int) slot;
|
return (int) slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns an indication if the replica node is fully available
|
||||||
|
* and should be listed in CLUSTER SLOTS response.
|
||||||
|
* Returns 1 for available nodes, 0 for nodes that have
|
||||||
|
* not finished their initial sync, in failed state, or are
|
||||||
|
* otherwise considered not available to serve read commands. */
|
||||||
|
static int isReplicaAvailable(clusterNode *node) {
|
||||||
|
if (nodeFailed(node)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
long long repl_offset = node->repl_offset;
|
||||||
|
if (node->flags & CLUSTER_NODE_MYSELF) {
|
||||||
|
/* Nodes do not update their own information
|
||||||
|
* in the cluster node list. */
|
||||||
|
repl_offset = replicationGetSlaveOffset();
|
||||||
|
}
|
||||||
|
return (repl_offset != 0);
|
||||||
|
}
|
||||||
|
|
||||||
void addNodeReplyForClusterSlot(client *c, clusterNode *node, int start_slot, int end_slot) {
|
void addNodeReplyForClusterSlot(client *c, clusterNode *node, int start_slot, int end_slot) {
|
||||||
int i, nested_elements = 3; /* slots (2) + master addr (1) */
|
int i, nested_elements = 3; /* slots (2) + master addr (1) */
|
||||||
void *nested_replylen = addReplyDeferredLen(c);
|
void *nested_replylen = addReplyDeferredLen(c);
|
||||||
@ -4434,7 +4452,7 @@ void addNodeReplyForClusterSlot(client *c, clusterNode *node, int start_slot, in
|
|||||||
for (i = 0; i < node->numslaves; i++) {
|
for (i = 0; i < node->numslaves; i++) {
|
||||||
/* This loop is copy/pasted from clusterGenNodeDescription()
|
/* This loop is copy/pasted from clusterGenNodeDescription()
|
||||||
* with modifications for per-slot node aggregation. */
|
* with modifications for per-slot node aggregation. */
|
||||||
if (nodeFailed(node->slaves[i])) continue;
|
if (!isReplicaAvailable(node->slaves[i])) continue;
|
||||||
addReplyArrayLen(c, 3);
|
addReplyArrayLen(c, 3);
|
||||||
addReplyBulkCString(c, node->slaves[i]->ip);
|
addReplyBulkCString(c, node->slaves[i]->ip);
|
||||||
/* Report slave's non-TLS port to non-TLS client in TLS cluster */
|
/* Report slave's non-TLS port to non-TLS client in TLS cluster */
|
||||||
|
103
tests/cluster/tests/22-replica-in-sync.tcl
Normal file
103
tests/cluster/tests/22-replica-in-sync.tcl
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
source "../tests/includes/init-tests.tcl"
|
||||||
|
|
||||||
|
test "Create a 1 node cluster" {
|
||||||
|
create_cluster 1 0
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Cluster is up" {
|
||||||
|
assert_cluster_state ok
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Cluster is writable" {
|
||||||
|
cluster_write_test 0
|
||||||
|
}
|
||||||
|
|
||||||
|
proc is_in_slots {master_id replica} {
|
||||||
|
set slots [R $master_id cluster slots]
|
||||||
|
set found_position [string first $replica $slots]
|
||||||
|
set result [expr {$found_position != -1}]
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
|
||||||
|
proc is_replica_online {info_repl} {
|
||||||
|
set found_position [string first "state=online" $info_repl]
|
||||||
|
set result [expr {$found_position != -1}]
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
|
||||||
|
set master_id 0
|
||||||
|
|
||||||
|
test "Fill up" {
|
||||||
|
R $master_id debug populate 10000000 key 100
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Add new node as replica" {
|
||||||
|
set replica_id [cluster_find_available_slave 1]
|
||||||
|
set master_myself [get_myself $master_id]
|
||||||
|
set replica_myself [get_myself $replica_id]
|
||||||
|
set replica [dict get $replica_myself id]
|
||||||
|
R $replica_id cluster replicate [dict get $master_myself id]
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Check digest and replica state" {
|
||||||
|
R 1 readonly
|
||||||
|
wait_for_condition 1000 50 {
|
||||||
|
[is_in_slots $master_id $replica]
|
||||||
|
} else {
|
||||||
|
fail "New replica didn't appear in the slots"
|
||||||
|
}
|
||||||
|
wait_for_condition 1000 50 {
|
||||||
|
[is_replica_online [R $master_id info replication]]
|
||||||
|
} else {
|
||||||
|
fail "Replica is down for too long"
|
||||||
|
}
|
||||||
|
set replica_digest [R $replica_id debug digest]
|
||||||
|
assert {$replica_digest ne 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Replica in loading state is hidden" {
|
||||||
|
# Kill replica client for master and load new data to the primary
|
||||||
|
R $master_id multi
|
||||||
|
R $master_id config set repl-backlog-size 100
|
||||||
|
R $master_id client kill type replica
|
||||||
|
set num 10000
|
||||||
|
set value [string repeat A 1024]
|
||||||
|
for {set j 0} {$j < $num} {incr j} {
|
||||||
|
set key "{0}"
|
||||||
|
append key $j
|
||||||
|
R $master_id set key $value
|
||||||
|
}
|
||||||
|
R $master_id exec
|
||||||
|
|
||||||
|
# Check that replica started loading
|
||||||
|
wait_for_condition 1000 50 {
|
||||||
|
[s $replica_id loading] eq 1
|
||||||
|
} else {
|
||||||
|
fail "Replica didn't enter loading state"
|
||||||
|
}
|
||||||
|
# Check that replica is not in cluster slots
|
||||||
|
assert {![is_in_slots $master_id $replica]}
|
||||||
|
|
||||||
|
# Wait for sync to finish
|
||||||
|
wait_for_condition 1000 50 {
|
||||||
|
[s $replica_id loading] eq 0
|
||||||
|
} else {
|
||||||
|
fail "Replica is in loading state for too long"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check replica is back to cluster slots
|
||||||
|
wait_for_condition 1000 50 {
|
||||||
|
[is_in_slots $master_id $replica]
|
||||||
|
} else {
|
||||||
|
fail "Replica is not back to slots"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Check disconnected replica not hidden from slots" {
|
||||||
|
# Disconnect replica from primary
|
||||||
|
R $master_id client kill type replica
|
||||||
|
# Check master to have no replicas
|
||||||
|
assert {[s $master_id connected_slaves] == 0}
|
||||||
|
# Check that replica is still in the cluster slots
|
||||||
|
assert {[is_in_slots $master_id $replica]}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user