summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorAli Mir <ali.mir@mongodb.com>2020-03-31 17:05:50 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-04-03 20:58:40 +0000
commit86cb9cf105c242a46a437366afbaa19fadcf5703 (patch)
treee227a06cb5344d8a3a658669c7ebf23300063501 /src/mongo/db
parent5c8919c258ffbfef1f5f331162cacf50ccbd3aeb (diff)
downloadmongo-86cb9cf105c242a46a437366afbaa19fadcf5703.tar.gz
SERVER-47211 Remove 4.2 style reconfig behavior on FCV downgrade
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/commands/set_feature_compatibility_version_command.cpp42
-rw-r--r--src/mongo/db/repl/repl_set_heartbeat_args_v1.cpp7
-rw-r--r--src/mongo/db/repl/repl_set_request_votes_args.cpp2
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.cpp3
-rw-r--r--src/mongo/db/repl/topology_coordinator.cpp40
-rw-r--r--src/mongo/db/repl/topology_coordinator_v1_test.cpp29
6 files changed, 4 insertions, 119 deletions
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 ad455262237..69062283c85 100644
--- a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
+++ b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
@@ -253,49 +253,11 @@ public:
FeatureCompatibilityVersion::setTargetDowngrade(opCtx);
- // Safe reconfig introduces a new "term" field in the config document. If the user tries
- // to downgrade the replset to FCV42, the primary will initiate a reconfig without the
- // term and wait for it to be replicated on all nodes.
- auto replCoord = repl::ReplicationCoordinator::get(opCtx);
- const bool isReplSet =
- replCoord->getReplicationMode() == repl::ReplicationCoordinator::modeReplSet;
- if (isReplSet &&
- replCoord->getConfig().getConfigTerm() != repl::OpTime::kUninitializedTerm) {
- // Force reconfig with term -1 to remove the 4.2 incompatible "term" field.
- auto getNewConfig = [&](const repl::ReplSetConfig& oldConfig, long long term) {
- auto newConfig = oldConfig;
- newConfig.setConfigTerm(repl::OpTime::kUninitializedTerm);
- newConfig.setConfigVersion(newConfig.getConfigVersion() + 1);
- return newConfig;
- };
-
- // "force" reconfig in order to skip safety checks. This is safe since the content
- // of config is the same.
- LOGV2(4628800, "Downgrading replica set config.");
- auto status = replCoord->doReplSetReconfig(opCtx, getNewConfig, true /* force */);
- uassertStatusOKWithContext(status, "Failed to downgrade the replica set config");
-
- LOGV2(4628801,
- "Waiting for the downgraded replica set config to propagate to all nodes");
- // If a write concern is given, we'll use its wTimeout. It's kNoTimeout by default.
- WriteConcernOptions writeConcern(repl::ReplSetConfig::kConfigAllWriteConcernName,
- WriteConcernOptions::SyncMode::NONE,
- opCtx->getWriteConcern().wTimeout);
- writeConcern.checkCondition = WriteConcernOptions::CheckCondition::Config;
- repl::OpTime fakeOpTime(Timestamp(1, 1), replCoord->getTerm());
- uassertStatusOKWithContext(
- replCoord->awaitReplication(opCtx, fakeOpTime, writeConcern).status,
- "Failed to wait for the downgraded replica set config to propagate to all "
- "nodes");
- LOGV2(4628802,
- "The downgraded replica set config has been propagated to all nodes");
- }
-
{
// Take the global lock in S mode to create a barrier for operations taking the
// global IX or X locks. This ensures that either
// - The global IX/X locked operation will start after the FCV change, see the
- // downgrading to 4.2 FCV and act accordingly.
+ // downgrading to 4.4 FCV and act accordingly.
// - The global IX/X locked operation began prior to the FCV change, is acting on
// that assumption and will finish before downgrade procedures begin right after
// this.
@@ -308,7 +270,7 @@ public:
if (serverGlobalParams.clusterRole == ClusterRole::ShardServer) {
LOGV2(20502, "Downgrade: dropping config.rangeDeletions collection");
migrationutil::dropRangeDeletionsCollection(opCtx);
- } else if (isReplSet || serverGlobalParams.clusterRole == ClusterRole::ConfigServer) {
+ } else if (serverGlobalParams.clusterRole == ClusterRole::ConfigServer) {
// The default rwc document should only be deleted on plain replica sets and the
// config server replica set, not on shards or standalones.
deletePersistedDefaultRWConcernDocument(opCtx);
diff --git a/src/mongo/db/repl/repl_set_heartbeat_args_v1.cpp b/src/mongo/db/repl/repl_set_heartbeat_args_v1.cpp
index e63d39611da..d97b1d15759 100644
--- a/src/mongo/db/repl/repl_set_heartbeat_args_v1.cpp
+++ b/src/mongo/db/repl/repl_set_heartbeat_args_v1.cpp
@@ -172,12 +172,7 @@ void ReplSetHeartbeatArgsV1::addToBSON(BSONObjBuilder* builder) const {
builder->append(kCheckEmptyFieldName, _checkEmpty);
}
builder->appendIntOrLL(kConfigVersionFieldName, _configVersion);
- // The configTerm field is new in 4.4 and cannot be parsed by MongoDB 4.2. Therefore omit it if
- // we have a 4.2-style replica set config with no "term". This permits us to downgrade by first
- // removing the replica set config's term, then downgrading to 4.2.
- if (_configTerm != OpTime::kUninitializedTerm) {
- builder->appendIntOrLL(kConfigTermFieldName, _configTerm);
- }
+ builder->appendIntOrLL(kConfigTermFieldName, _configTerm);
if (_hasHeartbeatVersion) {
builder->appendIntOrLL(kHeartbeatVersionFieldName, _hasHeartbeatVersion);
}
diff --git a/src/mongo/db/repl/repl_set_request_votes_args.cpp b/src/mongo/db/repl/repl_set_request_votes_args.cpp
index 0dff3a3e22c..b685bb0ab4e 100644
--- a/src/mongo/db/repl/repl_set_request_votes_args.cpp
+++ b/src/mongo/db/repl/repl_set_request_votes_args.cpp
@@ -83,8 +83,6 @@ Status ReplSetRequestVotesArgs::initialize(const BSONObj& argsObj) {
if (!status.isOK())
return status;
- // In order to be compatible with FCV 4.2, default the config term to -1 if we are unable
- // parse a configTerm field from the args.
status = bsonExtractIntegerFieldWithDefault(
argsObj, kConfigTermFieldName, OpTime::kUninitializedTerm, &_cfgTerm);
if (!status.isOK())
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp
index a13520f2b7c..005629813eb 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl.cpp
@@ -3278,8 +3278,7 @@ Status ReplicationCoordinatorImpl::doReplSetReconfig(OperationContext* opCtx,
// Make sure that the latest committed optime from the previous config is committed in the
// current config. If this is the initial reconfig, then we don't need to check this
// condition, since there were no prior configs. Also, for force reconfigs we bypass this
- // safety check condition. In any FCV < 4.4 we also bypass it to preserve client facing
- // behavior in mixed version sets.
+ // safety check condition.
auto isInitialReconfig = (_rsConfig.getConfigVersion() == 1);
// If our config was installed via a "force" reconfig, we bypass the oplog commitment check.
auto leavingForceConfig = (_rsConfig.getConfigTerm() == OpTime::kUninitializedTerm);
diff --git a/src/mongo/db/repl/topology_coordinator.cpp b/src/mongo/db/repl/topology_coordinator.cpp
index fc8fbdb487d..a4dc8a1dc73 100644
--- a/src/mongo/db/repl/topology_coordinator.cpp
+++ b/src/mongo/db/repl/topology_coordinator.cpp
@@ -1268,28 +1268,6 @@ StatusWith<bool> TopologyCoordinator::setLastOptime(const UpdatePositionArgs::Up
"appliedOpTime"_attr = args.appliedOpTime,
"durableOpTime"_attr = args.durableOpTime);
- // If we're in FCV 4.4, allow replSetUpdatePosition commands between config versions.
- if (!serverGlobalParams.featureCompatibility.isVersion(
- ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo44)) {
- if (args.cfgver != _rsConfig.getConfigVersion()) {
- static constexpr char errmsg[] =
- "Received replSetUpdatePosition for node whose config version doesn't match our "
- "config version";
- LOGV2_DEBUG(21813,
- 1,
- errmsg,
- "memberId"_attr = memberId,
- "memberConfigVersion"_attr = args.cfgver,
- "ourConfigVersion"_attr = _rsConfig.getConfigVersion());
- *configVersion = _rsConfig.getConfigVersion();
- return Status(ErrorCodes::InvalidReplicaSetConfig,
- str::stream()
- << errmsg << ", memberId: " << memberId
- << ", member config version: " << args.cfgver
- << ", our config version: " << _rsConfig.getConfigVersion());
- }
- }
-
// While we can accept replSetUpdatePosition commands across config versions, we still do not
// allow receiving them from a node that is not in our config.
auto* memberData = _findMemberDataByMemberId(memberId.getData());
@@ -2908,24 +2886,6 @@ bool TopologyCoordinator::shouldChangeSyncSource(const HostAndPort& currentSourc
return true;
}
- // If we're in FCV 4.4, allow data replication between config versions. Otherwise, change
- // our sync source.
- if (!serverGlobalParams.featureCompatibility.isVersion(
- ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo44)) {
- if (replMetadata.getConfigVersion() != _rsConfig.getConfigVersion()) {
- LOGV2(
- 21830,
- "Choosing new sync source because the config version supplied by {currentSource}, "
- "{syncSourceConfigVersion}, does not match ours, {configVersion}",
- "Choosing new sync source because the config version supplied by the current sync "
- "source does not match ours",
- "currentSource"_attr = currentSource,
- "syncSourceConfigVersion"_attr = replMetadata.getConfigVersion(),
- "configVersion"_attr = _rsConfig.getConfigVersion());
- return true;
- }
- }
-
// While we can allow data replication across config versions, we still do not allow syncing
// from a node that is not in our config.
const int currentSourceIndex = _rsConfig.findMemberIndexByHostAndPort(currentSource);
diff --git a/src/mongo/db/repl/topology_coordinator_v1_test.cpp b/src/mongo/db/repl/topology_coordinator_v1_test.cpp
index 87914e55c43..a77c4f8423c 100644
--- a/src/mongo/db/repl/topology_coordinator_v1_test.cpp
+++ b/src/mongo/db/repl/topology_coordinator_v1_test.cpp
@@ -2830,35 +2830,6 @@ TEST_F(PrepareHeartbeatResponseV1Test,
ASSERT_EQUALS(HostAndPort("h2"), response.getSyncingTo());
}
-TEST_F(TopoCoordTest, OmitUninitializedConfigTermFromHeartbeat) {
- // A MongoDB 4.2 replica set config with no term.
- updateConfig(BSON("_id"
- << "rs0"
- << "version" << 1 << "members"
- << BSON_ARRAY(BSON("_id" << 10 << "host"
- << "hself")
- << BSON("_id" << 20 << "host"
- << "h2"))),
- 0);
-
- // A member with this config omits configTerm from heartbeat requests.
- auto [request, timeout] =
- getTopoCoord().prepareHeartbeatRequestV1(Date_t(), "rs0", HostAndPort("h2", 27017));
- (void)timeout; // Unused.
-
- ASSERT_EQUALS(request.getConfigTerm(), -1);
- ASSERT_EQUALS(request.getConfigVersion(), 1);
- ASSERT_FALSE(request.toBSON().hasField("configTerm"_sd));
-
- // A member with this config omits configTerm from heartbeat responses.
- ReplSetHeartbeatArgsV1 args;
- args.setSetName("rs0");
- args.setSenderId(20);
- ReplSetHeartbeatResponse response;
- ASSERT_OK(getTopoCoord().prepareHeartbeatResponseV1(now()++, args, "rs0", &response));
- ASSERT_FALSE(response.toBSON().hasField("configTerm"_sd));
-}
-
TEST_F(TopoCoordTest, RespondToHeartbeatsWithNullLastAppliedAndLastDurableWhileInInitialSync) {
ASSERT_TRUE(TopologyCoordinator::Role::kFollower == getTopoCoord().getRole());
ASSERT_EQUALS(MemberState::RS_STARTUP, getTopoCoord().getMemberState().s);