Print an empty primary log when primary lost its last slot (#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 <binloveplay1314@qq.com>
Co-authored-by: Ping Xie <pingxie@outlook.com>
This commit is contained in:
Binbin 2024-09-23 13:14:09 +08:00 committed by GitHub
parent d07c29791a
commit 56fba564b6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 14 additions and 3 deletions

View File

@ -2670,7 +2670,7 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc
* If the sender and myself are in the same shard, try psync. */
clusterSetPrimary(sender, !are_in_same_shard, !are_in_same_shard);
clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_FSYNC_CONFIG);
} else if ((sender_slots >= migrated_our_slots) && !are_in_same_shard) {
} else if (nodeIsPrimary(myself) && (sender_slots >= migrated_our_slots) && !are_in_same_shard) {
/* When all our slots are lost to the sender and the sender belongs to
* a different shard, this is likely due to a client triggered slot
* migration. Don't reconfigure this node to migrate to the new shard
@ -6422,11 +6422,12 @@ void clusterCommandSetSlot(client *c) {
int slot_was_mine = server.cluster->slots[slot] == my_primary;
clusterDelSlot(slot);
clusterAddSlot(n, slot);
int shard_is_empty = my_primary->numslots == 0;
/* If replica migration is allowed, check if the primary of this shard
* loses its last slot and the shard becomes empty. In this case, we
* should turn into a replica of the new primary. */
if (server.cluster_allow_replica_migration && slot_was_mine && my_primary->numslots == 0) {
if (server.cluster_allow_replica_migration && slot_was_mine && shard_is_empty) {
serverAssert(n != my_primary);
serverLog(LL_NOTICE,
"Lost my last slot during slot migration. Reconfiguring myself "
@ -6442,6 +6443,16 @@ void clusterCommandSetSlot(client *c) {
clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_FSYNC_CONFIG);
}
/* If replica migration is not allowed, check if the primary of this shard
* loses its last slot and the shard becomes empty. In this case, we will
* print the exact same log as during the gossip process. */
if (!server.cluster_allow_replica_migration && nodeIsPrimary(myself) && slot_was_mine && shard_is_empty) {
serverAssert(n != my_primary);
serverLog(LL_NOTICE,
"My last slot was migrated to node %.40s (%s) in shard %.40s. I am now an empty primary.",
n->name, n->human_nodename, n->shard_id);
}
/* If this node or this node's primary was importing this slot,
* assigning the slot to itself also clears the importing status. */
if ((n == myself || n == myself->replicaof) && server.cluster->importing_slots_from[slot]) {

View File

@ -372,7 +372,7 @@ proc test_cluster_setslot {type} {
fail "valkey-cli --cluster rebalance returns non-zero exit code, output below:\n$result"
}
# Wait for R 3 to report that it is an empty replica (cluster-allow-replica-migration no)
# Wait for R 3 to report that it is an empty primary (cluster-allow-replica-migration no)
wait_for_log_messages -3 {"*I am now an empty primary*"} 0 1000 50
if {$type == "setslot"} {