SERVER-100309 Remove featureFlagSessionsCollectionCoordinatorOnConfigServer feature flag (#53319)

GitOrigin-RevId: 98a80fcf9d6626850f6828512f96f1798ddfc599
This commit is contained in:
Pol Piñol Castuera 2026-05-20 15:37:04 +02:00 committed by MongoDB Bot
parent 8249ada3db
commit f4f724d500
15 changed files with 101 additions and 530 deletions

View File

@ -20,7 +20,6 @@
- featureFlagGaplessFTDC
# TODO SERVER-67034: re-enable 'featureFlagSbeFull'.
- featureFlagSbeFull
- featureFlagSessionsCollectionCoordinatorOnConfigServer
# TODO (SERVER-108818): test primary-driven index builds in allFeatureFlag variant.
- featureFlagPrimaryDrivenIndexBuilds
- featureFlagResumablePrimaryDrivenIndexBuilds

View File

@ -6106,8 +6106,6 @@ function shouldSkipTestCase(clusterType, command, testCase, shardedCollection, w
}
if (testCase == "noop") {
// TODO SERVER-100309 adapt/enable setFeatureCompatibilityVersion no-op case once the
// upgrade procedure will not proactively shard the sessions collection.
if (
clusterType == "sharded" &&
(shardedDDLCommandsRequiringMajorityCommit.includes(command) ||

View File

@ -1,185 +0,0 @@
// Test that upgrade downgrade transfers the create collection coordinator for
// config.system.sessions collection between the shard and config server.
import {configureFailPoint} from "jstests/libs/fail_point_util.js";
import {FeatureFlagUtil} from "jstests/libs/feature_flag_util.js";
import {ShardingTest} from "jstests/libs/shardingtest.js";
import {removeShard} from "jstests/sharding/libs/remove_shard_util.js";
function dropSessionsCollectionManually(st) {
let collDoc = st.s.getDB("config").getCollection("collections").findOne({_id: "config.system.sessions"});
if (collDoc == undefined) {
return;
}
let uuid = collDoc.uuid;
assert.commandWorked(
st.s.getDB("config").getCollection("collections").deleteOne({
_id: "config.system.sessions",
}),
);
assert.commandWorked(st.s.getDB("config").getCollection("chunks").deleteMany({uuid: uuid}));
st.configRS.getPrimary().getDB("config").getCollection("system.sessions").drop();
st.shard0.getDB("config").getCollection("system.sessions").drop();
st.shard1.getDB("config").getCollection("system.sessions").drop();
assert.commandWorked(
st.configRS.getPrimary().adminCommand({_flushRoutingTableCacheUpdates: "config.system.sessions"}),
);
assert.commandWorked(st.shard0.adminCommand({_flushRoutingTableCacheUpdates: "config.system.sessions"}));
assert.commandWorked(st.shard1.adminCommand({_flushRoutingTableCacheUpdates: "config.system.sessions"}));
}
function checkSessionsCollectionPresent(conn, expectPresent) {
let result = conn.getDB("config").runCommand({listCollections: 1, filter: {name: "system.sessions"}});
let expectedLength = expectPresent ? 1 : 0;
assert.eq(result.cursor.firstBatch.length, expectedLength);
}
function checkSessionsCollectionConsistent(conn) {
const inconsistencies = conn.getDB("config").checkMetadataConsistency().toArray();
assert.eq(0, inconsistencies.length, tojson(inconsistencies));
}
function checkSessionsCollection(mongoSConnection, configSvrConnection, expectPresent) {
checkSessionsCollectionPresent(configSvrConnection, expectPresent);
checkSessionsCollectionConsistent(mongoSConnection);
}
function createSessionsCollectionAndCheck(mongoSConnection, configSvrConnection, expectPresent) {
assert.commandWorked(configSvrConnection.adminCommand({refreshLogicalSessionCacheNow: 1}));
checkSessionsCollection(mongoSConnection, configSvrConnection, expectPresent);
}
jsTest.log("Dedicated config server tests");
{
const st = new ShardingTest({
shards: 2,
other: {configOptions: {setParameter: {disableLogicalSessionCacheRefresh: true}}},
});
let expectCollectionOnCSRSAfterUpgrade = FeatureFlagUtil.isPresentAndEnabled(
st.shard0,
"SessionsCollectionCoordinatorOnConfigServer",
);
jsTest.log("Basic test case in new FCV");
dropSessionsCollectionManually(st);
createSessionsCollectionAndCheck(st.s, st.configRS.getPrimary(), expectCollectionOnCSRSAfterUpgrade);
jsTest.log("Test that downgrade drops the collection on the config server");
assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}));
checkSessionsCollection(st.s, st.configRS.getPrimary(), false /* old FCV */);
jsTest.log("Basic test in old FCV");
dropSessionsCollectionManually(st);
createSessionsCollectionAndCheck(st.s, st.configRS.getPrimary(), false /* old FCV */);
jsTest.log("Test that upgrade creates the collection on the config server");
assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: latestFCV, confirm: true}));
checkSessionsCollection(st.s, st.configRS.getPrimary(), expectCollectionOnCSRSAfterUpgrade);
// This test expects FCV upgrade to create the collection which only happens with the feature
// flag enabled
if (expectCollectionOnCSRSAfterUpgrade) {
jsTest.log("Downgrade again so we can do more upgrade tests");
assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}));
jsTest.log("Upgrading will create the sessions collection if it can (before upgrading)");
assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: latestFCV, confirm: true}));
checkSessionsCollection(st.s, st.configRS.getPrimary(), expectCollectionOnCSRSAfterUpgrade);
}
// These tests fail with the feature flag enabled (SERVER-105083 and SERVER-105096).
if (!expectCollectionOnCSRSAfterUpgrade) {
jsTest.log("Downgrade again so we can do more upgrade tests");
assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}));
dropSessionsCollectionManually(st);
jsTest.log("Upgrading will work even if the config server has a garbage version of the sessions collection");
createSessionsCollectionAndCheck(st.s, st.configRS.getPrimary(), false);
st.configRS.getPrimary().getDB("config").getCollection("system.sessions").drop();
assert.commandWorked(st.configRS.getPrimary().getDB("config").createCollection("system.sessions"));
assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: latestFCV, confirm: true}));
checkSessionsCollectionPresent(st.configRS.getPrimary(), true /* garbage version present */);
jsTest.log("Downgrade again so we can do more upgrade tests");
assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}));
dropSessionsCollectionManually(st);
jsTest.log("Upgrading will work even if there are multiple shards in the collection");
createSessionsCollectionAndCheck(st.s, st.configRS.getPrimary(), false);
assert.commandWorked(st.s.adminCommand({split: "config.system.sessions", middle: {_id: 0}}));
assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: latestFCV, confirm: true}));
checkSessionsCollection(st.s, st.configRS.getPrimary(), expectCollectionOnCSRSAfterUpgrade);
}
jsTest.log("Fail downgrade early so we can re-upgrade");
let failFCV = configureFailPoint(st.configRS.getPrimary(), "failDowngrading");
assert.commandFailedWithCode(
st.s.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}),
549181,
);
failFCV.off();
dropSessionsCollectionManually(st);
createSessionsCollectionAndCheck(st.s, st.configRS.getPrimary(), false);
jsTest.log("Re-upgrading should create the collection on the config server");
assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: latestFCV, confirm: true}));
checkSessionsCollection(st.s, st.configRS.getPrimary(), expectCollectionOnCSRSAfterUpgrade);
st.stop();
}
jsTest.log("Embedded config server tests");
{
const st = new ShardingTest({
shards: 2,
configShard: true,
other: {configOptions: {setParameter: {disableLogicalSessionCacheRefresh: true}}},
});
let expectCollectionOnCSRSAfterUpgrade = FeatureFlagUtil.isPresentAndEnabled(
st.shard0,
"SessionsCollectionCoordinatorOnConfigServer",
);
jsTest.log("Basic test case in new FCV");
dropSessionsCollectionManually(st);
createSessionsCollectionAndCheck(
st.s,
st.configRS.getPrimary(),
true /* embedded config server will be the first shard */,
);
st.startBalancer();
jsTest.log("Transition to dedicated shouldn't drop the collection");
removeShard(st, "config");
checkSessionsCollection(st.s, st.configRS.getPrimary(), expectCollectionOnCSRSAfterUpgrade);
jsTest.log("Transition from dedicated shouldn't drop the collection");
assert.commandWorked(st.s.adminCommand({transitionFromDedicatedConfigServer: 1}));
checkSessionsCollection(st.s, st.configRS.getPrimary(), expectCollectionOnCSRSAfterUpgrade);
st.stopBalancer();
jsTest.log("Downgrade to test config transitions on lower FCV");
dropSessionsCollectionManually(st);
createSessionsCollectionAndCheck(
st.s,
st.configRS.getPrimary(),
true /* embedded config server will be the first shard */,
);
assert.commandWorked(st.s.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}));
// Expect the chunk to be on the config server so downgrade shouldn't drop the collection.
checkSessionsCollection(st.s, st.configRS.getPrimary(), true);
jsTest.log("Transition to dedicated should drop the collection");
st.startBalancer();
removeShard(st, "config");
checkSessionsCollection(st.s, st.configRS.getPrimary(), false /* coordinator always off */);
jsTest.log("Transition from dedicated should drop the collection");
assert.commandWorked(st.configRS.getPrimary().getDB("config").createCollection("system.sessions"));
assert.commandWorked(st.s.adminCommand({transitionFromDedicatedConfigServer: 1}));
checkSessionsCollection(st.s, st.configRS.getPrimary(), false /* coordinator always off */);
st.stop();
}

View File

@ -305,11 +305,7 @@ const newShardName = assert.commandWorked(st.s.adminCommand({addShard: newShardR
assert(!configPrimary.getCollection(ns).exists());
assert(!configPrimary.getCollection(indexedNs).exists());
assert.sameMembers(configPrimary.getCollection(indexedNs).getIndexKeys(), []);
if (FeatureFlagUtil.isPresentAndEnabled(configPrimary, "SessionsCollectionCoordinatorOnConfigServer")) {
assert(configPrimary.getCollection("config.system.sessions").exists());
} else {
assert(!configPrimary.getCollection("config.system.sessions").exists());
}
assert(!configPrimary.getCollection("config.system.sessions").exists());
// Basic CRUD and sharded DDL work.
basicCRUD(st.s);

View File

@ -758,15 +758,6 @@ private:
opCtx, CoordinatorTypeEnum::kRenameCollection);
}
// TODO (SERVER-100309): Remove once 9.0 becomes last lts.
if (feature_flags::gSessionsCollectionCoordinatorOnConfigServer
.isDisabledOnTargetFCVButEnabledOnOriginalFCV(requestedVersion,
originalVersion)) {
ShardingCoordinatorService::getService(opCtx)
->waitForCoordinatorsOfGivenTypeToComplete(
opCtx, CoordinatorTypeEnum::kCreateCollection);
}
// TODO SERVER-77915: Remove once v8.0 branches out.
if (feature_flags::gTrackUnshardedCollectionsUponMoveCollection
.isDisabledOnTargetFCVButEnabledOnOriginalFCV(requestedVersion,

View File

@ -35,10 +35,9 @@
#include "mongo/db/dbdirectclient.h"
#include "mongo/db/dbhelpers.h"
#include "mongo/db/generic_argument_util.h"
#include "mongo/db/global_catalog/ddl/cluster_ddl.h"
#include "mongo/db/global_catalog/ddl/drop_collection_coordinator.h"
#include "mongo/db/global_catalog/ddl/placement_history_commands_gen.h"
#include "mongo/db/global_catalog/ddl/sharding_catalog_manager.h"
#include "mongo/db/global_catalog/ddl/sharding_coordinator.h"
#include "mongo/db/global_catalog/ddl/sharding_coordinator_gen.h"
#include "mongo/db/global_catalog/ddl/sharding_coordinator_service.h"
#include "mongo/db/global_catalog/ddl/sharding_ddl_util.h"
@ -463,13 +462,6 @@ private:
}
}
// TODO (SERVER-100309): Remove once 9.0 becomes last lts.
if (isConfigsvr &&
feature_flags::gSessionsCollectionCoordinatorOnConfigServer.isEnabledOnVersion(
requestedVersion)) {
_createConfigSessionsCollectionLocally(opCtx);
}
// The content of config.placementHistory needs to be recomputed after ensuring that all
// shards (including a possible embedded config server) reached the kComplete FCV phase, so
// that the routine has to be invoked here (rather than embedding it within
@ -507,22 +499,6 @@ private:
}
}
void _createConfigSessionsCollectionLocally(OperationContext* opCtx) {
ShardsvrCreateCollection shardsvrCollRequest(NamespaceString::kLogicalSessionsNamespace);
ShardsvrCreateCollectionRequest requestParamsObj;
requestParamsObj.setShardKey(BSON("_id" << 1));
shardsvrCollRequest.setShardsvrCreateCollectionRequest(std::move(requestParamsObj));
shardsvrCollRequest.setDbName(NamespaceString::kLogicalSessionsNamespace.dbName());
try {
cluster::createCollection(opCtx, std::move(shardsvrCollRequest));
} catch (const ExceptionFor<ErrorCodes::IllegalOperation>& ex) {
LOGV2(8694900,
"Failed to create config.system.sessions on upgrade",
"error"_attr = redact(ex));
}
}
// TODO (SERVER-98118): Remove once v9.0 become last-lts.
void _resetPlacementHistory(OperationContext* opCtx, const FCV requestedVersion) {
if (!feature_flags::gFeatureFlagChangeStreamPreciseShardTargeting.isEnabledOnVersion(
@ -972,11 +948,6 @@ private:
_cleanUpClusterParameters(opCtx, originalVersion, requestedVersion);
_createAuthzSchemaVersionDocIfNeeded(opCtx);
// Note the config server is also considered a shard, so the ConfigServer and ShardServer
// roles aren't mutually exclusive.
if (role && role->has(ClusterRole::ConfigServer)) {
_dropSessionsCollectionLocally(opCtx, requestedVersion, originalVersion);
}
if (role && role->has(ClusterRole::ShardServer)) {
abortAllMultiUpdateCoordinators(opCtx, requestedVersion, originalVersion);
@ -1095,32 +1066,6 @@ private:
}
}
void _dropSessionsCollectionLocally(OperationContext* opCtx,
const FCV requestedVersion,
const FCV originalVersion) {
if (feature_flags::gSessionsCollectionCoordinatorOnConfigServer
.isDisabledOnTargetFCVButEnabledOnOriginalFCV(requestedVersion, originalVersion)) {
// Only drop the collection locally if the config server is not acting as a shard. Since
// addShard (transitionFromDedicated) cannot run on transitional FCV, we cannot drop
// this when we shouldn't. If we transition to dedicated after this check, then
// transition to dedicated will drop the collection.
const auto allShardIds = Grid::get(opCtx)->shardRegistry()->getAllShardIds(opCtx);
bool amIAConfigShard =
std::find(allShardIds.begin(),
allShardIds.end(),
ShardingState::get(opCtx)->shardId()) != allShardIds.end();
if (!amIAConfigShard) {
DropCollectionCoordinator::dropCollectionLocally(
opCtx,
NamespaceString::kLogicalSessionsNamespace,
true /* fromMigrate */,
true /* dropSystemCollections */,
boost::none,
false /* requireCollectionEmpty */);
}
}
}
void abortAllMultiUpdateCoordinators(OperationContext* opCtx,
const FCV requestedVersion,
const FCV originalVersion) {

View File

@ -85,7 +85,6 @@ std::vector<AsyncRequestsSender::Request> buildUntrackedRequestsForAllShards(
return requests;
}
// TODO (SERVER-100309): remove once 9.0 becomes last LTS.
AsyncRequestsSender::Response executeCommandAgainstFirstShard(OperationContext* opCtx,
const DatabaseName& dbName,
const NamespaceString& nss,
@ -162,8 +161,7 @@ CachedDatabaseInfo createDatabase(OperationContext* opCtx,
}
CreateCollectionResponse createCollection(OperationContext* opCtx,
ShardsvrCreateCollection request,
bool againstFirstShard) {
ShardsvrCreateCollection request) {
const auto& nss = request.getNamespace();
if (MONGO_unlikely(hangCreateUnshardedCollection.shouldFail()) && request.getUnsplittable() &&
@ -262,14 +260,7 @@ CreateCollectionResponse createCollection(OperationContext* opCtx,
boost::optional<executor::RemoteCommandResponse> remoteResponse;
// TODO (SERVER-100309): remove againstFirstShard option once 9.0 becomes last LTS.
if (againstFirstShard) {
tassert(
113986,
"createCollection can only run against the first shard for `config.system.sessions` "
"collection.",
nss == NamespaceString::kLogicalSessionsNamespace);
if (isSharded && nss.isConfigDB()) {
const auto dbInfo =
uassertStatusOK(Grid::get(opCtx)->catalogCache()->getDatabase(opCtx, nss.dbName()));
const auto cmdResponse =

View File

@ -53,11 +53,9 @@ createDatabase(OperationContext* opCtx,
/**
* Creates the specified collection.
*
* TODO (SERVER-100309): remove `againstFirstShard` once 9.0 becomes last LTS.
*/
MONGO_MOD_NEEDS_REPLACEMENT CreateCollectionResponse createCollection(
OperationContext* opCtx, ShardsvrCreateCollection request, bool againstFirstShard = false);
MONGO_MOD_NEEDS_REPLACEMENT CreateCollectionResponse
createCollection(OperationContext* opCtx, ShardsvrCreateCollection request);
/**
* Creates a collection with the options specified in `request`. Calls the above createCollection

View File

@ -882,13 +882,10 @@ void checkShardingCatalogCollectionOptions(OperationContext* opCtx,
boost::optional<CreateCollectionResponse> checkIfCollectionExistsWithSameOptions(
OperationContext* opCtx,
const ShardsvrCreateCollectionRequest& request,
const NamespaceString& originalNss,
bool newSessionsCollectionPath) {
const NamespaceString& originalNss) {
boost::optional<NamespaceString> optTargetNss;
boost::optional<UUID> optTargetCollUUID;
// TODO (SERVER-100309): Remove once 9.0 becomes last LTS.
bool missingSessionsCollectionLocally = false;
{
// 1. Check if the collection already exists in the local catalog with same options
@ -904,14 +901,7 @@ boost::optional<CreateCollectionResponse> checkIfCollectionExistsWithSameOptions
}
if (!targetColl->exists()) {
// TODO (SERVER-100309): Remove once 9.0 becomes last LTS.
if (newSessionsCollectionPath &&
originalNss == NamespaceString::kLogicalSessionsNamespace) {
optTargetNss = originalNss;
missingSessionsCollectionLocally = true;
} else {
return boost::none;
}
return boost::none;
} else {
optTargetNss = targetColl->nss();
optTargetCollUUID = targetColl->uuid();
@ -925,9 +915,7 @@ boost::optional<CreateCollectionResponse> checkIfCollectionExistsWithSameOptions
tassert(10644538, "Expected optTargetNss to be set", optTargetNss);
const auto& targetNss = *optTargetNss;
tassert(10644539,
"Expected optTargetCollUUID to be set unless creating system.sessions",
optTargetCollUUID || missingSessionsCollectionLocally);
tassert(10644539, "Expected optTargetCollUUID to be set", optTargetCollUUID);
// 2. Make sure we're not trying to track a temporary aggregation collection upon moveCollection
if (request.getRegisterExistingCollectionInGlobalCatalog()) {
@ -959,14 +947,6 @@ boost::optional<CreateCollectionResponse> checkIfCollectionExistsWithSameOptions
Grid::get(opCtx)->catalogCache()->getCollectionPlacementInfoWithRefresh(opCtx, targetNss));
if (!cm.hasRoutingTable()) {
// If the sessions collection does not already exist we need to make sure that there is an
// available shard for us to make it on.
if (targetNss == NamespaceString::kLogicalSessionsNamespace) {
uassert(ErrorCodes::IllegalOperation,
"There are no suitable shards to create the sessions collection on",
Grid::get(opCtx)->shardRegistry()->getNumShards(opCtx) != 0);
}
// The collection is not tracked in the sharding catalog. We either need to register it or
// to shard it. Proceed with the coordinator.
return boost::none;
@ -1000,18 +980,6 @@ boost::optional<CreateCollectionResponse> checkIfCollectionExistsWithSameOptions
return boost::none;
}
// If the sessions collection exists in the sharding catalog but not locally, we want to
// run the coordinator so that we can create the collection locally. This is also true if we
// have a mismatched uuid locally - we want to run the coordinator and replace the local version
// of the collection.
//
// TODO (SERVER-100309): Remove once 9.0 becomes last LTS.
if (missingSessionsCollectionLocally ||
(targetNss == NamespaceString::kLogicalSessionsNamespace &&
!cm.uuidMatches(*optTargetCollUUID))) {
return boost::none;
}
// The collection already exists and match the requested options
CreateCollectionResponse response(ShardVersionFactory::make(cm));
response.setCollectionUUID(cm.getUUID());
@ -1747,11 +1715,8 @@ void CreateCollectionCoordinator::_checkPreconditions(OperationContext* opCtx) {
// Perform a preliminary check on whether the request may resolve into a no-op before acquiring
// any critical section.
auto createCollectionResponseOpt = checkIfCollectionExistsWithSameOptions(
opCtx,
_request,
originalNss(),
_doc.getCreateSessionsCollectionRemotelyOnFirstShard().value_or(false));
auto createCollectionResponseOpt =
checkIfCollectionExistsWithSameOptions(opCtx, _request, originalNss());
if (createCollectionResponseOpt) {
_result = createCollectionResponseOpt;
// Launch an exception to directly jump to the end of the continuation chain
@ -1765,9 +1730,7 @@ void CreateCollectionCoordinator::_checkPreconditions(OperationContext* opCtx) {
// This is important in order to fix a race where create collection for 'config.system.session',
// which is sent to a random shard, could otherwise execute on a config server that is no longer
// a data-bearing shard.
// TODO (SERVER-100309): Remove this once 9.0 becomes last LTS.
if (!_doc.getCreateSessionsCollectionRemotelyOnFirstShard() &&
ShardingState::get(opCtx)->pollClusterRole()->has(ClusterRole::ConfigServer)) {
if (ShardingState::get(opCtx)->pollClusterRole()->has(ClusterRole::ConfigServer)) {
const auto allShardIds = Grid::get(opCtx)->shardRegistry()->getAllShardIds(opCtx);
bool amIAConfigShard = std::find(allShardIds.begin(),
allShardIds.end(),
@ -1945,23 +1908,7 @@ void CreateCollectionCoordinator::_syncIndexesOnCoordinator(
const CancellationToken& token) {
// If the collection does not exist or the current data shard is the coordinator, then the
// indexes on the coordinator will already be accurate.
bool collectionExists = [&] {
// During the transition from running the create coordintor for config.system.sessions on
// the first shard to running it on the config server, the collection may be sharded but the
// collection will not exist locally on the config server. This logic will ensure that we
// create the collection locally on the config server the first time the coordinator is run
// on the config server.
//
// TODO (SERVER-100309): Remove once 9.0 becomes last LTS
if (_doc.getCreateSessionsCollectionRemotelyOnFirstShard() &&
nss() == NamespaceString::kLogicalSessionsNamespace) {
const auto cri = uassertStatusOK(
Grid::get(opCtx)->catalogCache()->getCollectionRoutingInfo(opCtx, nss()));
return cri.hasRoutingTable();
} else {
return sharding_ddl_util::getCollectionUUID(opCtx, nss()).is_initialized();
}
}();
bool collectionExists = sharding_ddl_util::getCollectionUUID(opCtx, nss()).is_initialized();
if (!collectionExists || *_doc.getOriginalDataShard() == ShardingState::get(opCtx)->shardId()) {
return;
}
@ -1973,23 +1920,8 @@ void CreateCollectionCoordinator::_syncIndexesOnCoordinator(
}
auto optUuid = sharding_ddl_util::getCollectionUUID(opCtx, nss());
// TODO (SERVER-100309): Remove sessions collection handling once 9.0 becomes last LTS.
if (!optUuid) {
tassert(10644508,
"Expected the namespace to be system.sessions",
nss() == NamespaceString::kLogicalSessionsNamespace);
tassert(10644509,
"Expected createSessionsCollectionRemotelyOnFirstShard to be set on the "
"coordinator document",
_doc.getCreateSessionsCollectionRemotelyOnFirstShard());
// If we are in the state described above, we cannot get the uuid locally and so we need to
// take the existing one from config.collections.
const auto& cri = uassertStatusOK(
Grid::get(opCtx)->catalogCache()->getCollectionRoutingInfo(opCtx, nss()));
_uuid = cri.getChunkManager().getUUID();
} else {
_uuid = *optUuid;
}
tassert(10644508, "Expected collection UUID to be available locally", optUuid);
_uuid = *optUuid;
// Get indexes from the dataShard and copy them to the coordinator.
const auto session = getNewSession(opCtx);
@ -2031,15 +1963,8 @@ void CreateCollectionCoordinator::_createCollectionOnCoordinator(
_request.getUnique().value_or(false));
}
auto dataShardForPolicy =
const auto dataShardForPolicy =
_request.getDataShard() ? _request.getDataShard() : _doc.getOriginalDataShard();
if (_doc.getCreateSessionsCollectionRemotelyOnFirstShard() &&
nss() == NamespaceString::kLogicalSessionsNamespace &&
dataShardForPolicy == ShardingState::get(opCtx)->shardId()) {
auto allShardIds = Grid::get(opCtx)->shardRegistry()->getAllShardIds(opCtx);
std::sort(allShardIds.begin(), allShardIds.end());
dataShardForPolicy = allShardIds[0];
}
const auto splitPolicy = create_collection_util::createPolicy(
opCtx,
shardKeyPattern,

View File

@ -110,11 +110,3 @@ structs:
shard if the collection does not yet exist. Only guaranteed to be set after the
enterWriteCSOnDataShardAndCheckEmpty phase completes.
optional: true
# TODO (SERVER-100309): remove once 9.0 becomes last LTS
createSessionsCollectionRemotelyOnFirstShard:
type: bool
description: >-
When true, the coordinator will set the first shard as the data shard for the
config.system.sessions collection. When false, the coordinator will create the
chunk for the sessions collection locally (pre-8.1 behavior).
optional: true

View File

@ -47,7 +47,6 @@
#include "mongo/db/global_catalog/ddl/sharding_ddl_util.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/server_feature_flags_gen.h"
#include "mongo/db/server_options.h"
#include "mongo/db/service_context.h"
#include "mongo/db/shard_role/ddl/ddl_lock_manager.h"
@ -256,25 +255,15 @@ public:
}
}
// Check whether we should create config.system.sessions from the config server on
// the first shard using dataShard. Will throw if the feature flag is enabled and
// we are on a shard server.
//
// TODO (SERVER-100309): remove once 9.0 becomes last LTS.
bool useNewCoordinatorPathForSessionsColl =
_checkSessionsFeatureFlagAndClusterRole(opCtx, ns(), *optFixedFcvRegion);
// If we are in the old world (where the config.system.sessions coordinator is run
// on the first shard) we need to route the command to the first shard unless we
// are the first shard.
//
// TODO (SERVER-100309): remove once 9.0 becomes last LTS.
// Routers do not know FCV and can still follow the old behavior by sending
// config.system.sessions create requests to the config server. Until all routers
// have upgraded, route those requests to the first shard so they reach the
// coordinator. Once 9.0 becomes last LTS, only embedded config servers should reach
// this path and it can be removed.
// TODO (SERVER-127204): Remove once 9.0 becomes last LTS.
if (boost::optional<Response> remoteCreateResponse =
_routeSessionsCollectionCreateIfNeeded(
opCtx,
ns(),
useNewCoordinatorPathForSessionsColl,
request().getShardsvrCreateCollectionRequest()))
opCtx, request().getShardsvrCreateCollectionRequest()))
return *remoteCreateResponse;
auto requestToForward = request().getShardsvrCreateCollectionRequest();
@ -298,9 +287,6 @@ public:
auto doc = CreateCollectionCoordinatorDocument();
doc.setShardingCoordinatorMetadata({{ns(), coordType}});
doc.setShardsvrCreateCollectionRequest(requestToForward);
if (useNewCoordinatorPathForSessionsColl) {
doc.setCreateSessionsCollectionRemotelyOnFirstShard(true);
}
return doc.toBSON();
}();
@ -360,40 +346,11 @@ public:
return CreateCollectionResponse{ShardVersion::UNTRACKED()};
}
// TODO (SERVER-100309): remove once 9.0 becomes last LTS.
bool _checkSessionsFeatureFlagAndClusterRole(OperationContext* opCtx,
const NamespaceString& nss,
const FixedFCVRegion& fixedFcvRegion) {
if (ns() != NamespaceString::kLogicalSessionsNamespace)
return false;
// If the feature flag is enabled, we must be running on the config server
// and we want to tell the coordinator that it must not create the
// collection locally.
auto clusterRole = ShardingState::get(opCtx)->pollClusterRole();
if (feature_flags::gSessionsCollectionCoordinatorOnConfigServer.isEnabled(
VersionContext::getDecoration(opCtx), fixedFcvRegion->acquireFCVSnapshot())) {
uassert(ErrorCodes::CommandNotSupported,
"Sessions collection can only be sharded on the config server",
!clusterRole->hasExclusively(ClusterRole::ShardServer));
return true;
}
return false;
}
// TODO (SERVER-100309): remove once 9.0 becomes last LTS.
boost::optional<Response> _routeSessionsCollectionCreateIfNeeded(
OperationContext* opCtx,
const NamespaceString& nss,
bool useNewPathForSessionsColl,
ShardsvrCreateCollectionRequest request) {
if (ns() != NamespaceString::kLogicalSessionsNamespace || useNewPathForSessionsColl)
OperationContext* opCtx, ShardsvrCreateCollectionRequest request) {
if (ns() != NamespaceString::kLogicalSessionsNamespace)
return boost::none;
// If the feature flag is disabled, we should check whether we are the first
// shard (which can be the case in embedded config scenarios). If so, we
// should run the coordinator normally. Otherwise we should route the
// command appropriately.
auto clusterRole = ShardingState::get(opCtx)->pollClusterRole();
if (clusterRole->has(ClusterRole::ConfigServer)) {
auto allShardIds = Grid::get(opCtx)->shardRegistry()->getAllShardIds(opCtx);
@ -403,7 +360,7 @@ public:
ShardsvrCreateCollection requestToForward(ns());
requestToForward.setShardsvrCreateCollectionRequest(request);
requestToForward.setDbName(ns().dbName());
return cluster::createCollection(opCtx, std::move(requestToForward), true);
return cluster::createCollection(opCtx, std::move(requestToForward));
}
}
return boost::none;

View File

@ -905,9 +905,8 @@ bool _collectionMustExistLocallyButDoesnt(OperationContext* opCtx,
const ShardId& currentShard,
const ShardId& primaryShard) {
// The DBPrimary shard must always have the collection created locally regardless if it owns
// chunks or not.
//
// TODO (SERVER-100309): Remove exclusion for configDB once 9.0 becomes lastLTS.
// chunks or not. The config database is excluded because config.system.sessions is created on
// the first shard instead of the database primary.
if (currentShard == primaryShard && !nss.isConfigDB()) {
return true;
}

View File

@ -146,14 +146,6 @@ feature_flags:
default: false
fcv_gated: true
enable_on_transitional_fcv_UNSAFE: true
# TODO (SERVER-100309): remove once 9.0 becomes last LTS.
featureFlagSessionsCollectionCoordinatorOnConfigServer:
description:
Feature flag for running the shard collection coordinator on the config server for
config.system.sessions.
cpp_varname: feature_flags::gSessionsCollectionCoordinatorOnConfigServer
default: false
fcv_gated: true
featureFlagTerminateSecondaryReadsUponRangeDeletion:
description: "Feature flag to enable the termination of secondary reads due to range deletions."
cpp_varname: feature_flags::gTerminateSecondaryReadsUponRangeDeletion

View File

@ -428,74 +428,6 @@ protected:
ASSERT_EQUALS(addedShard.getHost(), logEntry.getDetails()["host"].String());
}
// TODO (SERVER-100309): move into SuccessfullyAddConfigShard test once 9.0 becomes LastLTS.
void runSuccessfulConfigShardTest(bool expectDropSessionsCollection) {
std::unique_ptr<RemoteCommandTargeterMock> targeter(
std::make_unique<RemoteCommandTargeterMock>());
ConnectionString connString =
assertGet(ConnectionString::parse("mySet/host1:12345,host2:12345"));
targeter->setConnectionStringReturnValue(connString);
HostAndPort shardTarget = connString.getServers().front();
targeter->setFindHostReturnValue(shardTarget);
targeterFactory()->addTargeterToReturn(connString, std::move(targeter));
std::string expectedShardName = "mySet";
// The shard doc inserted into the config.shards collection on the config server.
ShardType expectedShard;
expectedShard.setName(expectedShardName);
expectedShard.setHost(connString.toString());
DatabaseType discoveredDB(DatabaseName::createDatabaseName_forTest(boost::none, "shardDB"),
ShardId(expectedShardName),
DatabaseVersion(UUID::gen(), Timestamp(1, 1)));
auto future = launchAsync([this, &expectedShardName, &connString] {
ThreadClient tc(getServiceContext()->getService());
auto opCtx = Client::getCurrent()->makeOperationContext();
auto shardName = assertGet(ShardingCatalogManager::get(opCtx.get())
->addShard(opCtx.get(),
FixedFCVRegion(opCtx.get()),
nullptr,
connString,
true /* isConfigShard */));
ASSERT_EQUALS(expectedShardName, shardName);
});
BSONArrayBuilder hosts;
hosts.append("host1:12345");
hosts.append("host2:12345");
BSONObj commandResponse = BSON("ok" << 1 << "isWritablePrimary" << true << "setName"
<< "mySet"
<< "hosts" << hosts.arr() << "maxWireVersion"
<< WireVersion::LATEST_WIRE_VERSION);
expectHello(shardTarget, commandResponse);
expectHello(shardTarget, commandResponse);
// Get databases list from new shard
expectListDatabases(
shardTarget,
std::vector<BSONObj>{BSON("name" << discoveredDB.getDbName().toString_forTest())});
if (expectDropSessionsCollection) {
expectCollectionDrop(shardTarget, NamespaceString::kLogicalSessionsNamespace);
}
// Should not run _addShard command, touch user_writes_critical_sections, setParameter,
// setFCV
// Wait for the addShard to complete before checking the config database
future.timed_get(kLongFutureTimeout);
// Ensure that the shard document was properly added to config.shards.
assertShardExists(expectedShard);
// Ensure that the databases detected from the shard were properly added to config.database.
assertDatabaseExists(discoveredDB);
assertChangeWasLogged(expectedShard);
}
OID _clusterId;
ReadWriteConcernDefaultsLookupMock _lookupMock;
@ -948,15 +880,69 @@ TEST_F(AddShardTest, SuccessfullyAddReplicaSet) {
checkLocalClusterParametersAfterPull();
}
// TODO (SERVER-100309): remove once 9.0 becomes last LTS.
TEST_F(AddShardTest, SuccessfullyAddConfigShardOldPath) {
RAIIServerParameterControllerForTest featureFlagController(
"featureFlagSessionsCollectionCoordinatorOnConfigServer", true);
runSuccessfulConfigShardTest(false);
}
TEST_F(AddShardTest, SuccessfullyAddConfigShard) {
runSuccessfulConfigShardTest(true);
std::unique_ptr<RemoteCommandTargeterMock> targeter(
std::make_unique<RemoteCommandTargeterMock>());
ConnectionString connString =
assertGet(ConnectionString::parse("mySet/host1:12345,host2:12345"));
targeter->setConnectionStringReturnValue(connString);
HostAndPort shardTarget = connString.getServers().front();
targeter->setFindHostReturnValue(shardTarget);
targeterFactory()->addTargeterToReturn(connString, std::move(targeter));
std::string expectedShardName = "mySet";
// The shard doc inserted into the config.shards collection on the config server.
ShardType expectedShard;
expectedShard.setName(expectedShardName);
expectedShard.setHost(connString.toString());
DatabaseType discoveredDB(DatabaseName::createDatabaseName_forTest(boost::none, "shardDB"),
ShardId(expectedShardName),
DatabaseVersion(UUID::gen(), Timestamp(1, 1)));
auto future = launchAsync([this, &expectedShardName, &connString] {
ThreadClient tc(getServiceContext()->getService());
auto opCtx = Client::getCurrent()->makeOperationContext();
auto shardName = assertGet(ShardingCatalogManager::get(opCtx.get())
->addShard(opCtx.get(),
FixedFCVRegion(opCtx.get()),
nullptr,
connString,
true /* isConfigShard */));
ASSERT_EQUALS(expectedShardName, shardName);
});
BSONArrayBuilder hosts;
hosts.append("host1:12345");
hosts.append("host2:12345");
BSONObj commandResponse = BSON("ok" << 1 << "isWritablePrimary" << true << "setName"
<< "mySet"
<< "hosts" << hosts.arr() << "maxWireVersion"
<< WireVersion::LATEST_WIRE_VERSION);
expectHello(shardTarget, commandResponse);
expectHello(shardTarget, commandResponse);
// Get databases list from new shard
expectListDatabases(
shardTarget,
std::vector<BSONObj>{BSON("name" << discoveredDB.getDbName().toString_forTest())});
expectCollectionDrop(shardTarget, NamespaceString::kLogicalSessionsNamespace);
// Should not run _addShard command, touch user_writes_critical_sections, setParameter,
// setFCV
// Wait for the addShard to complete before checking the config database
future.timed_get(kLongFutureTimeout);
// Ensure that the shard document was properly added to config.shards.
assertShardExists(expectedShard);
// Ensure that the databases detected from the shard were properly added to config.database.
assertDatabaseExists(discoveredDB);
assertChangeWasLogged(expectedShard);
}
TEST_F(AddShardTest, ReplicaSetExtraHostsDiscovered) {

View File

@ -106,7 +106,6 @@
#include "mongo/db/sharding_environment/grid.h"
#include "mongo/db/sharding_environment/shard_id.h"
#include "mongo/db/sharding_environment/sharding_config_server_parameters_gen.h"
#include "mongo/db/sharding_environment/sharding_feature_flags_gen.h"
#include "mongo/db/sharding_environment/sharding_logging.h"
#include "mongo/db/tenant_id.h"
#include "mongo/db/topology/add_shard_gen.h"
@ -449,10 +448,7 @@ StatusWith<std::string> ShardingCatalogManager::addShard(
}
}
// Check that the shard candidate does not have a local config.system.sessions collection. We do
// not want to drop this once featureFlagSessionsCollectionCoordinatorOnConfigServer is enabled
// but we do not have stability yet. We optimistically do not drop it here and then double check
// later under the fixed FCV region.
// Check that the shard candidate does not have a local config.system.sessions collection.
if (!isConfigShard) {
auto res = _dropSessionsCollection(opCtx, targeter);
if (!res.isOK()) {
@ -495,9 +491,7 @@ StatusWith<std::string> ShardingCatalogManager::addShard(
currentFCV == multiversion::GenericFCV::kLastContinuous ||
currentFCV == multiversion::GenericFCV::kLastLTS);
if (isConfigShard &&
!feature_flags::gSessionsCollectionCoordinatorOnConfigServer.isEnabled(
VersionContext::getDecoration(opCtx), fcvSnapshot)) {
if (isConfigShard) {
auto res = _dropSessionsCollection(opCtx, targeter);
if (!res.isOK()) {
return res.withContext(
@ -928,21 +922,14 @@ RemoveShardProgress ShardingCatalogManager::removeShard(OperationContext* opCtx,
}
// Also drop the sessions collection, which we assume is the only sharded collection in
// the config database. Only do this if
// featureFlagSessionsCollectionCoordinatorOnConfigServer is disabled. We don't have
// synchronization with setFCV here, so it is still possible for rare interleavings to
// drop the collection when they shouldn't, but the create coordinator will re-create it
// on the next periodic refresh.
if (!feature_flags::gSessionsCollectionCoordinatorOnConfigServer.isEnabled(
VersionContext::getDecoration(opCtx), fcvRegion->acquireFCVSnapshot())) {
DBDirectClient client(opCtx);
BSONObj result;
if (!client.dropCollection(
NamespaceString::kLogicalSessionsNamespace,
ShardingCatalogClient::writeConcernLocalHavingUpstreamWaiter(),
&result)) {
uassertStatusOK(getStatusFromCommandResult(result));
}
// the config database.
DBDirectClient client(opCtx);
BSONObj result;
if (!client.dropCollection(
NamespaceString::kLogicalSessionsNamespace,
ShardingCatalogClient::writeConcernLocalHavingUpstreamWaiter(),
&result)) {
uassertStatusOK(getStatusFromCommandResult(result));
}
}