SERVER-114666 Forbid tracking temporary collections in the global catalog (#44712)

Co-authored-by: Meryama <meryama.nadim@mongodb.com>
GitOrigin-RevId: 846502ac4f506d58d3afc3520bc88c35231a5f16
This commit is contained in:
Joan Bruguera Micó (at MongoDB) 2025-12-08 16:37:44 +00:00 committed by MongoDB Bot
parent f4a99d4c56
commit 09a5166929
4 changed files with 59 additions and 5 deletions

View File

@ -346,7 +346,7 @@ class _AddRemoveShardThread(threading.Thread):
if err.code == self._ILLEGAL_OPERATION:
if "Can't move an internal resharding collection" in str(err):
return True
if "Can't reshard a timeseries collection" in str(err):
if "Can't register a temporary collection" in str(err):
return True
for regex in self._UNMOVABLE_NAMESPACE_REGEXES:
if re.search(regex, namespace):

View File

@ -93,6 +93,8 @@ last-continuous:
ticket: SERVER-114005
- test_file: jstests/sharding/move_collection_stale_mongos.js
ticket: SERVER-109322
- test_file: jstests/core_sharding/ddl/cannot_track_temporary_collection.js
ticket: SERVER-114666
- test_file: jstests/sharding/unshard_collection_stale_mongos.js
ticket: SERVER-109322
- test_file: jstests/sharding/reshard_collection_with_zones_stale_mongos.js
@ -696,6 +698,8 @@ last-lts:
ticket: SERVER-114005
- test_file: jstests/sharding/move_collection_stale_mongos.js
ticket: SERVER-109322
- test_file: jstests/core_sharding/ddl/cannot_track_temporary_collection.js
ticket: SERVER-114666
- test_file: jstests/sharding/unshard_collection_stale_mongos.js
ticket: SERVER-109322
- test_file: jstests/sharding/reshard_collection_with_zones_stale_mongos.js

View File

@ -0,0 +1,46 @@
/**
* Tests that temporary collections (i.e. with temp=true in the collection options)
* can not be tracked in the global catalog. Those collections are inherently local,
* and are dropped upon step up in a sharding-unaware way.
*
* @tags: [
* # The test tries to move a collection across shards.
* requires_2_or_more_shards,
* # Creates temporary collections, which are always unsharded.
* assumes_unsharded_collection,
* # Temporary collections are dropped on stepdowns.
* does_not_support_stepdowns,
* ]
*/
import {getRandomShardName} from "jstests/libs/sharded_cluster_fixture_helpers.js";
import {DiscoverTopology} from "jstests/libs/discover_topology.js";
assert.commandWorked(db.adminCommand({enableSharding: db.getName()}));
const primaryShardId = db.getDatabasePrimaryShardId();
const otherShardId = getRandomShardName(db, [primaryShardId]);
const topology = DiscoverTopology.findConnectedNodes(db);
const primaryShardConn = new Mongo(topology.shards[primaryShardId].primary);
// Temporary collections are only created internally by operations such as convertToCapped,
// and can not be created by users. For testing purposes, create one via applyOps.
const coll = db.getCollection("tmpcoll");
assert(coll.drop());
assert.commandWorked(
primaryShardConn.adminCommand({
applyOps: [{op: "c", ns: db.getName() + ".$cmd", o: {create: coll.getName(), temp: true}}],
}),
);
assert.commandFailedWithCode(
db.adminCommand({shardCollection: coll.getFullName(), key: {x: 1}}),
ErrorCodes.IllegalOperation,
);
assert.commandFailedWithCode(
db.adminCommand({moveCollection: coll.getFullName(), toShard: otherShardId}),
ErrorCodes.IllegalOperation,
);
// Since the collection isn't tracked, it can be dropped locally without causing a MissingLocalCollection inconsistency.
assert(primaryShardConn.getDB(db.getName()).getCollection(coll.getName()).drop());
const inconsistencies = db.checkMetadataConsistency().toArray();
assert.eq(0, inconsistencies.length, tojson(inconsistencies));

View File

@ -691,10 +691,14 @@ void checkLocalCatalogCollectionOptions(OperationContext* opCtx,
"expected the target collection to exist",
targetColl.has_value() && targetColl->exists());
uassert(ErrorCodes::IllegalOperation,
"Can't register a temporary collection in the sharding catalog.",
!targetColl->getCollectionPtr()->isTemporary());
assertTimeseriesLocalCatalogConsistency(opCtx, targetColl->getCollectionPtr().get());
if (request.getRegisterExistingCollectionInGlobalCatalog()) {
// No need to check for collection options when registering an existing collection
// No need to check for further collection options when registering an existing collection
return;
}
@ -921,14 +925,14 @@ boost::optional<CreateCollectionResponse> checkIfCollectionExistsWithSameOptions
"Expected optTargetCollUUID to be set unless creating system.sessions",
optTargetCollUUID || missingSessionsCollectionLocally);
// 2. Make sure we're not trying to track a temporary collection upon moveCollection
// 2. Make sure we're not trying to track a temporary aggregation collection upon moveCollection
if (request.getRegisterExistingCollectionInGlobalCatalog()) {
DBDirectClient client(opCtx);
const auto isTemporaryCollection =
const auto isTemporaryAggregationCollection =
client.count(NamespaceString::kAggTempCollections,
BSON("_id" << NamespaceStringUtil::serialize(
*optTargetNss, SerializationContext::stateDefault())));
if (isTemporaryCollection) {
if (isTemporaryAggregationCollection) {
// Return UNTRACKED version for the coordinator to gracefully terminate without
// registering the collection
return CreateCollectionResponse{ShardVersion::UNTRACKED()};