Skip to content

Commit caeca60

Browse files
enjoy-binbinPingXie
authored andcommitted
Print an empty primary log when primary lost its last slot (valkey-io#1064)
The one in CLUSTER SETSLOT help us keep track of state better, of course it also can make the test case happy. The one in gossip process fixes a problem that a replica can print a log saying it is an empty primary. Signed-off-by: Binbin <[email protected]> Co-authored-by: Ping Xie <[email protected]> Signed-off-by: naglera <[email protected]>
1 parent 7113811 commit caeca60

File tree

2 files changed

+14
-3
lines changed

2 files changed

+14
-3
lines changed

src/cluster_legacy.c

+13-2
Original file line numberDiff line numberDiff line change
@@ -2670,7 +2670,7 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc
26702670
* If the sender and myself are in the same shard, try psync. */
26712671
clusterSetPrimary(sender, !are_in_same_shard, !are_in_same_shard);
26722672
clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_FSYNC_CONFIG);
2673-
} else if ((sender_slots >= migrated_our_slots) && !are_in_same_shard) {
2673+
} else if (nodeIsPrimary(myself) && (sender_slots >= migrated_our_slots) && !are_in_same_shard) {
26742674
/* When all our slots are lost to the sender and the sender belongs to
26752675
* a different shard, this is likely due to a client triggered slot
26762676
* migration. Don't reconfigure this node to migrate to the new shard
@@ -6422,11 +6422,12 @@ void clusterCommandSetSlot(client *c) {
64226422
int slot_was_mine = server.cluster->slots[slot] == my_primary;
64236423
clusterDelSlot(slot);
64246424
clusterAddSlot(n, slot);
6425+
int shard_is_empty = my_primary->numslots == 0;
64256426

64266427
/* If replica migration is allowed, check if the primary of this shard
64276428
* loses its last slot and the shard becomes empty. In this case, we
64286429
* should turn into a replica of the new primary. */
6429-
if (server.cluster_allow_replica_migration && slot_was_mine && my_primary->numslots == 0) {
6430+
if (server.cluster_allow_replica_migration && slot_was_mine && shard_is_empty) {
64306431
serverAssert(n != my_primary);
64316432
serverLog(LL_NOTICE,
64326433
"Lost my last slot during slot migration. Reconfiguring myself "
@@ -6442,6 +6443,16 @@ void clusterCommandSetSlot(client *c) {
64426443
clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_FSYNC_CONFIG);
64436444
}
64446445

6446+
/* If replica migration is not allowed, check if the primary of this shard
6447+
* loses its last slot and the shard becomes empty. In this case, we will
6448+
* print the exact same log as during the gossip process. */
6449+
if (!server.cluster_allow_replica_migration && nodeIsPrimary(myself) && slot_was_mine && shard_is_empty) {
6450+
serverAssert(n != my_primary);
6451+
serverLog(LL_NOTICE,
6452+
"My last slot was migrated to node %.40s (%s) in shard %.40s. I am now an empty primary.",
6453+
n->name, n->human_nodename, n->shard_id);
6454+
}
6455+
64456456
/* If this node or this node's primary was importing this slot,
64466457
* assigning the slot to itself also clears the importing status. */
64476458
if ((n == myself || n == myself->replicaof) && server.cluster->importing_slots_from[slot]) {

tests/unit/cluster/replica-migration.tcl

+1-1
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ proc test_cluster_setslot {type} {
372372
fail "valkey-cli --cluster rebalance returns non-zero exit code, output below:\n$result"
373373
}
374374

375-
# Wait for R 3 to report that it is an empty replica (cluster-allow-replica-migration no)
375+
# Wait for R 3 to report that it is an empty primary (cluster-allow-replica-migration no)
376376
wait_for_log_messages -3 {"*I am now an empty primary*"} 0 1000 50
377377

378378
if {$type == "setslot"} {

0 commit comments

Comments
 (0)