Skip to content

Commit 23a1e95

Browse files
author
honchowchen
committed
[feature] mongod: add auto promote hidden
1 parent b3376e3 commit 23a1e95

File tree

3 files changed

+46
-3
lines changed

3 files changed

+46
-3
lines changed

src/mongo/db/repl/repl_set_config.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,14 @@ class ReplSetConfig : private MutableReplSetConfig {
439439
return getSettings()->getChainingAllowed();
440440
}
441441

442+
/**
443+
* Returns true if hidden nodes should be automatically promoted when all non-hidden
444+
* secondary nodes are unhealthy.
445+
*/
446+
bool getAutoPromoteHidden() const {
447+
return getSettings()->getAutoPromoteHidden();
448+
}
449+
442450
/**
443451
* Returns whether all members of this replica set have hostname localhost.
444452
*/

src/mongo/db/repl/repl_set_config.idl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ structs:
137137
type: objectid
138138
optional: true
139139
validator: { callback: "validateReplicaSetIdNotNull"}
140+
autoPromoteHidden:
141+
type: safeBool
142+
default: false
143+
description: "When true, allows hidden nodes to be automatically promoted to appear
144+
in the hosts list when all non-hidden secondary nodes are unhealthy"
140145

141146
ReplSetConfigBase:
142147
description: "The complete configuration for the replica set"

src/mongo/db/repl/topology_coordinator.cpp

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2321,13 +2321,43 @@ void TopologyCoordinator::fillHelloForReplSet(std::shared_ptr<HelloResponse> res
23212321

23222322
invariant(!_rsConfig.members().empty());
23232323

2324+
bool promoteHidden = true;
2325+
if (_rsConfig.getAutoPromoteHidden()) {
2326+
for (int i = 0; i < _rsConfig.getNumMembers(); i++) {
2327+
const auto& memberCfg = _rsConfig.getMemberAt(i);
2328+
if (memberCfg.isHidden()) {
2329+
// Only consider non-hidden secondaries for health check
2330+
continue;
2331+
}
2332+
const auto& memberData = _memberData.at(i);
2333+
// Check if this is a healthy secondary
2334+
bool isHealthySecondary = false;
2335+
if (i == _selfIndex) {
2336+
// For self, we are always "up", just check if we are secondary
2337+
isHealthySecondary = myState.secondary();
2338+
} else {
2339+
// For other members, check both state and health from heartbeat data
2340+
isHealthySecondary = memberData.getState().secondary() && memberData.up();
2341+
}
2342+
2343+
if (isHealthySecondary) {
2344+
promoteHidden = false;
2345+
break;
2346+
}
2347+
}
2348+
} else {
2349+
promoteHidden = false;
2350+
}
2351+
23242352
for (const auto& member : _rsConfig.members()) {
2325-
if (member.isHidden() || member.getSecondaryDelay() > Seconds{0}) {
2353+
if (member.getSecondaryDelay() > Seconds{0}) {
23262354
continue;
23272355
}
23282356
auto hostView = member.getHostAndPort(horizonString);
23292357

2330-
if (member.isElectable()) {
2358+
if (member.isHidden() && promoteHidden) {
2359+
response->addHost(std::move(hostView));
2360+
} else if (member.isElectable()) {
23312361
response->addHost(std::move(hostView));
23322362
} else if (member.isArbiter()) {
23332363
response->addArbiter(std::move(hostView));
@@ -2359,7 +2389,7 @@ void TopologyCoordinator::fillHelloForReplSet(std::shared_ptr<HelloResponse> res
23592389
if (selfConfig.getSecondaryDelay() > Seconds(0)) {
23602390
response->setSecondaryDelaySecs(selfConfig.getSecondaryDelay());
23612391
}
2362-
if (selfConfig.isHidden()) {
2392+
if (selfConfig.isHidden() && !promoteHidden) {
23632393
response->setIsHidden(true);
23642394
}
23652395
if (!selfConfig.shouldBuildIndexes()) {

0 commit comments

Comments
 (0)