blob: b78c9104a868f444c3b39ff65dd442de237fce9a [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <string>
#include <unordered_set>
#include "kudu/consensus/metadata.pb.h"
#include "kudu/util/status.h"
namespace kudu {
namespace consensus {
enum RaftConfigState {
PENDING_CONFIG,
COMMITTED_CONFIG,
ACTIVE_CONFIG,
};
bool IsRaftConfigMember(const std::string& uuid, const RaftConfigPB& config);
bool IsRaftConfigVoter(const std::string& uuid, const RaftConfigPB& config);
// Whether the specified Raft role is attributed to a peer which can participate
// in leader elections.
bool IsVoterRole(RaftPeerPB::Role role);
// Get the specified member of the config.
// Returns Status::NotFound if a member with the specified uuid could not be
// found in the config.
Status GetRaftConfigMember(RaftConfigPB* config,
const std::string& uuid,
RaftPeerPB** peer_pb);
// Get the leader of the consensus configuration.
// Returns Status::NotFound() if the leader RaftPeerPB could not be found in
// the config, or if there is no leader defined.
Status GetRaftConfigLeader(ConsensusStatePB* cstate, RaftPeerPB** peer_pb);
// Modifies 'configuration' remove the peer with the specified 'uuid'.
// Returns false if the server with 'uuid' is not found in the configuration.
// Returns true on success.
bool RemoveFromRaftConfig(RaftConfigPB* config, const std::string& uuid);
// Returns true iff the two peers have equivalent replica types and associated
// options.
bool ReplicaTypesEqual(const RaftPeerPB& peer1, const RaftPeerPB& peer2);
// Counts the number of voters in the configuration.
int CountVoters(const RaftConfigPB& config);
// Calculates size of a configuration majority based on # of voters.
int MajoritySize(int num_voters);
// Determines the role that the peer with uuid 'peer_uuid' plays in the
// cluster. If 'peer_uuid' is empty or is not a member of the configuration,
// this function will return NON_PARTICIPANT, regardless of whether it is
// specified as the leader in 'leader_uuid'. Likewise, if 'peer_uuid' is a
// NON_VOTER in the config, this function will return LEARNER, regardless of
// whether it is specified as the leader in 'leader_uuid' (although that
// situation is illegal in practice).
RaftPeerPB::Role GetConsensusRole(const std::string& peer_uuid,
const std::string& leader_uuid,
const RaftConfigPB& config);
// Same as above, but uses the leader and active role from the given
// ConsensusStatePB.
RaftPeerPB::Role GetConsensusRole(const std::string& peer_uuid,
const ConsensusStatePB& cstate);
// Same as above, but requires that the given 'peer' is a participant
// in the committed configuration in specified consensus state.
// If not, it will return incorrect results.
RaftPeerPB::Role GetParticipantRole(const RaftPeerPB& peer,
const ConsensusStatePB& cstate);
// Verifies that the provided configuration is well formed.
Status VerifyRaftConfig(const RaftConfigPB& config);
// Superset of checks performed by VerifyRaftConfig. Also ensures that the
// leader is a configuration voter, if it is set, and that a valid term is set.
Status VerifyConsensusState(const ConsensusStatePB& cstate);
// Provide a textual description of the difference between two consensus states,
// suitable for logging.
std::string DiffConsensusStates(const ConsensusStatePB& old_state,
const ConsensusStatePB& new_state);
// Same as the above, but just the RaftConfigPB portion of the configuration.
std::string DiffRaftConfigs(const RaftConfigPB& old_config,
const RaftConfigPB& new_config);
// Return 'true' iff there is a quorum and the specified tablet configuration
// is under-replicated given the 'replication_factor', ignoring failures of
// the UUIDs in 'uuids_ignored_for_underreplication'.
//
// The decision is based on the health information provided by the Raft
// configuration in the 'config' parameter.
bool ShouldAddReplica(const RaftConfigPB& config,
int replication_factor,
const std::unordered_set<std::string>& uuids_ignored_for_underreplication =
std::unordered_set<std::string>());
// Check if the given Raft configuration contains at least one extra replica
// which should (and can) be removed in accordance with the specified
// replication factor and current Raft leader. If so, and if a healthy majority
// exists, then return 'true' and set the UUID of the best candidate for
// eviction into the 'uuid_to_evict' out parameter. Otherwise, return 'false'.
bool ShouldEvictReplica(const RaftConfigPB& config,
const std::string& leader_uuid,
int replication_factor,
std::string* uuid_to_evict = nullptr);
} // namespace consensus
} // namespace kudu