mirror of
https://github.com/bitnami/containers.git
synced 2026-10-17 13:29:31 +02:00
[bitnami/mongodb-sharded] Ensure secondary keeps votes and priority after restart (#95156)
When a secondary first joins a replica set, mongodb_configure_secondary()
adds it with votes:0/priority:0 (MongoDB's recommended safe procedure) and
only grants voting rights on that freshly-added code path. If a previous
attempt added the node but the container failed or was restarted before the
voting-rights step ran, the next boot takes the "node already in cluster"
branch and skips promotion entirely. The member is then left stranded at
votes:0/priority:0 forever.
With a 3-node set this can silently leave a single voting member, turning
that node into a single point of failure: if it goes down the set can no
longer elect a primary and goes read-only.
This makes the voting-rights grant idempotent and re-runnable:
- add mongodb_secondary_node_has_voting_rights() to check whether a member
already has votes>0 && priority>0;
- grant voting rights whenever they are missing, even for a node that is
already in the cluster, so an interrupted bootstrap converges to
votes:1/priority:1 on the next run;
- fix the misleading error message printed for the voting step
("did not get marked as secondary" -> "did not get granted voting rights").
Signed-off-by: Edouard COMTET <edouard.comtet@scality.com>
This commit is contained in:
@@ -941,6 +941,32 @@ EOF
|
||||
grep -q "ok: 1" <<<"$result"
|
||||
}
|
||||
|
||||
########################
|
||||
# Get if secondary node already has voting rights
|
||||
# Globals:
|
||||
# MONGODB_*
|
||||
# Arguments:
|
||||
# $1 - node
|
||||
# $2 - port
|
||||
# Returns:
|
||||
# Boolean
|
||||
#########################
|
||||
mongodb_secondary_node_has_voting_rights() {
|
||||
local -r node="${1:?node is required}"
|
||||
local -r port="${2:?port is required}"
|
||||
local result
|
||||
|
||||
debug "Checking voting rights of the node"
|
||||
result=$(
|
||||
mongodb_execute_print_output "$MONGODB_INITIAL_PRIMARY_ROOT_USER" "$MONGODB_INITIAL_PRIMARY_ROOT_PASSWORD" "admin" "$MONGODB_INITIAL_PRIMARY_HOST" "$MONGODB_INITIAL_PRIMARY_PORT_NUMBER" <<EOF
|
||||
rs.conf().members.filter(m => m.host === '$node:$port' && m.votes > 0 && m.priority > 0).length === 1
|
||||
EOF
|
||||
)
|
||||
debug "$result"
|
||||
|
||||
grep -q "true" <<<"$result"
|
||||
}
|
||||
|
||||
########################
|
||||
# Get if hidden node is pending
|
||||
# Globals:
|
||||
@@ -1177,7 +1203,15 @@ mongodb_configure_secondary() {
|
||||
exit 1
|
||||
fi
|
||||
mongodb_wait_confirmation "$node" "$port"
|
||||
fi
|
||||
|
||||
# Grant voting rights to the node if it does not have them yet. This must be
|
||||
# done even when the node is already in the cluster: a previous attempt may
|
||||
# have added it with votes/priority 0 and failed (or been restarted) before
|
||||
# granting voting rights, leaving the node stuck without them.
|
||||
if mongodb_secondary_node_has_voting_rights "$node" "$port"; then
|
||||
info "Node already has voting rights"
|
||||
else
|
||||
# Ensure that secondary nodes do not count as voting members until they are fully initialized
|
||||
# https://docs.mongodb.com/manual/reference/method/rs.add/#behavior
|
||||
if ! retry_while "mongodb_is_secondary_node_ready $node $port" "$MONGODB_INIT_RETRY_ATTEMPTS" "$MONGODB_INIT_RETRY_DELAY"; then
|
||||
@@ -1188,17 +1222,16 @@ mongodb_configure_secondary() {
|
||||
# Grant voting rights to node
|
||||
# https://docs.mongodb.com/manual/tutorial/modify-psa-replica-set-safely/
|
||||
if ! retry_while "mongodb_configure_secondary_node_voting $node $port" "$MONGODB_INIT_RETRY_ATTEMPTS" "$MONGODB_INIT_RETRY_DELAY"; then
|
||||
error "Secondary node did not get marked as secondary"
|
||||
error "Secondary node did not get granted voting rights"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Mark node as readable. This is necessary in cases where the PVC is lost
|
||||
if is_boolean_yes "$MONGODB_SET_SECONDARY_OK"; then
|
||||
mongodb_execute_print_output "$MONGODB_INITIAL_PRIMARY_ROOT_USER" "$MONGODB_INITIAL_PRIMARY_ROOT_PASSWORD" "admin" <<EOF
|
||||
# Mark node as readable. This is necessary in cases where the PVC is lost
|
||||
if is_boolean_yes "$MONGODB_SET_SECONDARY_OK"; then
|
||||
mongodb_execute_print_output "$MONGODB_INITIAL_PRIMARY_ROOT_USER" "$MONGODB_INITIAL_PRIMARY_ROOT_PASSWORD" "admin" <<EOF
|
||||
rs.secondaryOk()
|
||||
EOF
|
||||
fi
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user