diff options
author | Ali Mir <ali.mir@mongodb.com> | 2020-03-31 17:05:50 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-04-03 20:58:40 +0000 |
commit | 86cb9cf105c242a46a437366afbaa19fadcf5703 (patch) | |
tree | e227a06cb5344d8a3a658669c7ebf23300063501 /src/mongo/db | |
parent | 5c8919c258ffbfef1f5f331162cacf50ccbd3aeb (diff) | |
download | mongo-86cb9cf105c242a46a437366afbaa19fadcf5703.tar.gz |
SERVER-47211 Remove 4.2 style reconfig behavior on FCV downgrade
Diffstat (limited to 'src/mongo/db')
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); |