summaryrefslogtreecommitdiff
path: root/src/mongo/db/commands
diff options
context:
space:
mode:
authorLuxi Liu <luxi.liu@mongodb.com>2022-08-08 16:30:42 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-08-08 17:33:11 +0000
commit2a13beec826c4ac5369125327ddd79f496a16e62 (patch)
tree1a47236f2c562dfd579f821d2b0ae6a2de833542 /src/mongo/db/commands
parentd7d2858267ec5133ad7491c985c37424481f689c (diff)
downloadmongo-2a13beec826c4ac5369125327ddd79f496a16e62.tar.gz
SERVER-67958 added downgrading->upgrading path, always generate new timestamp for configSvr, and test file
Diffstat (limited to 'src/mongo/db/commands')
-rw-r--r--src/mongo/db/commands/feature_compatibility_version.cpp10
-rw-r--r--src/mongo/db/commands/set_feature_compatibility_version_command.cpp59
2 files changed, 37 insertions, 32 deletions
diff --git a/src/mongo/db/commands/feature_compatibility_version.cpp b/src/mongo/db/commands/feature_compatibility_version.cpp
index ee65c3df6be..674be1c4ff1 100644
--- a/src/mongo/db/commands/feature_compatibility_version.cpp
+++ b/src/mongo/db/commands/feature_compatibility_version.cpp
@@ -109,6 +109,10 @@ public:
// lastLTS then the second loop iteration just overwrites the first.
_transitions[{from, to, isFromConfigServer}] = upgrading;
_transitions[{upgrading, to, isFromConfigServer}] = to;
+ // allow downgrading->upgrading->latest path
+ _transitions[{GenericFCV::kDowngradingFromLatestToLastLTS,
+ GenericFCV::kLatest,
+ isFromConfigServer}] = GenericFCV::kUpgradingFromLastLTSToLatest;
}
_fcvDocuments[upgrading] = makeFCVDoc(from /* effective */, to /* target */);
}
@@ -326,7 +330,11 @@ void FeatureCompatibilityVersion::updateFeatureCompatibilityVersionDocument(
// Only transition to fully upgraded or downgraded states when we
// have completed all required upgrade/downgrade behavior.
auto transitioningVersion = setTargetVersion &&
- serverGlobalParams.featureCompatibility.isUpgradingOrDowngrading(fromVersion)
+ serverGlobalParams.featureCompatibility.isUpgradingOrDowngrading(fromVersion) &&
+ // if kDowngradingFromLatestToLastLTS->kLatest, we want to get the transitional version
+ // i.e. kUpgradingFromLastLTSToLatest
+ !(fromVersion == GenericFCV::kDowngradingFromLatestToLastLTS &&
+ newVersion == GenericFCV::kLatest)
? fromVersion
: fcvTransitions.getTransitionalVersion(fromVersion, newVersion, isFromConfigServer);
FeatureCompatibilityVersionDocument fcvDoc =
diff --git a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
index 008228dabcc..5b8c50b4641 100644
--- a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
+++ b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
@@ -293,37 +293,7 @@ public:
return true;
}
- boost::optional<Timestamp> changeTimestamp;
- if (serverGlobalParams.clusterRole == ClusterRole::ConfigServer) {
- // The Config Server creates a new ID (i.e., timestamp) when it receives an upgrade or
- // downgrade request. Alternatively, the request refers to a previously aborted
- // operation for which the local FCV document must contain the ID to be reused.
- if (!serverGlobalParams.featureCompatibility.isUpgradingOrDowngrading()) {
- const auto now = VectorClock::get(opCtx)->getTime();
- changeTimestamp = now.clusterTime().asTimestamp();
- } else {
- auto fcvObj =
- FeatureCompatibilityVersion::findFeatureCompatibilityVersionDocument(opCtx);
- auto fcvDoc = FeatureCompatibilityVersionDocument::parse(
- IDLParserContext("featureCompatibilityVersionDocument"), fcvObj.value());
- changeTimestamp = fcvDoc.getChangeTimestamp();
- uassert(5722800,
- "The 'changeTimestamp' field is missing in the FCV document persisted by "
- "the Config Server. This may indicate that this document has been "
- "explicitly amended causing an internal data inconsistency.",
- changeTimestamp);
- }
- } else if (serverGlobalParams.clusterRole == ClusterRole::ShardServer &&
- request.getPhase()) {
- // Shards receive the timestamp from the Config Server's request.
- changeTimestamp = request.getChangeTimestamp();
- uassert(5563500,
- "The 'changeTimestamp' field is missing even though the node is running as a "
- "shard. This may indicate that the 'setFeatureCompatibilityVersion' command "
- "was invoked directly against the shard or that the config server has not been "
- "upgraded to at least version 5.0.",
- changeTimestamp);
- }
+ const boost::optional<Timestamp> changeTimestamp = getChangeTimestamp(opCtx, request);
FeatureCompatibilityVersion::validateSetFeatureCompatibilityVersionRequest(
opCtx, request, actualVersion);
@@ -774,6 +744,33 @@ private:
}
}
+ /**
+ * For sharded cluster servers:
+ * Generate a new changeTimestamp if change fcv is called on config server,
+ * otherwise retrieve changeTimestamp from the Config Server request.
+ */
+ boost::optional<Timestamp> getChangeTimestamp(mongo::OperationContext* opCtx,
+ mongo::SetFeatureCompatibilityVersion request) {
+ boost::optional<Timestamp> changeTimestamp;
+ if (serverGlobalParams.clusterRole == ClusterRole::ConfigServer) {
+ // The Config Server always creates a new ID (i.e., timestamp) when it receives an
+ // upgrade or downgrade request.
+ const auto now = VectorClock::get(opCtx)->getTime();
+ changeTimestamp = now.clusterTime().asTimestamp();
+ } else if (serverGlobalParams.clusterRole == ClusterRole::ShardServer &&
+ request.getPhase()) {
+ // Shards receive the timestamp from the Config Server's request.
+ changeTimestamp = request.getChangeTimestamp();
+ uassert(5563500,
+ "The 'changeTimestamp' field is missing even though the node is running as a "
+ "shard. This may indicate that the 'setFeatureCompatibilityVersion' command "
+ "was invoked directly against the shard or that the config server has not been "
+ "upgraded to at least version 5.0.",
+ changeTimestamp);
+ }
+ return changeTimestamp;
+ }
+
} setFeatureCompatibilityVersionCommand;
} // namespace