summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2020-02-26 10:22:56 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-02-26 16:17:26 +0000
commit62a6b963bc20ba74d2f3e0d62552dc3b7b1f1133 (patch)
tree5df6b7bec1eca18ba682214572bb853dd0edabfa
parentb41cd4b2c416e965fc3541c97cd0b51563d90c40 (diff)
downloadmongo-62a6b963bc20ba74d2f3e0d62552dc3b7b1f1133.tar.gz
SERVER-45599 Backport of SERVER-39495: Only return versioned filtering metadata for cases that actually need to do filtering
This is a partial cherry-pick from 851dad7902d6bb8c3ed25f99f565a2e2c8c8bc47, adapted for the 4.0 branch.
-rw-r--r--src/mongo/db/commands/count_cmd.cpp6
-rw-r--r--src/mongo/db/commands/geo_near_cmd.cpp6
-rw-r--r--src/mongo/db/commands/mr.cpp2
-rw-r--r--src/mongo/db/exec/update.cpp1
-rw-r--r--src/mongo/db/op_observer_impl.cpp2
-rw-r--r--src/mongo/db/pipeline/pipeline_d.cpp2
-rw-r--r--src/mongo/db/query/get_executor.cpp7
-rw-r--r--src/mongo/db/query/stage_builder.cpp10
-rw-r--r--src/mongo/db/s/collection_metadata.cpp110
-rw-r--r--src/mongo/db/s/collection_metadata.h110
-rw-r--r--src/mongo/db/s/collection_metadata_filtering_test.cpp6
-rw-r--r--src/mongo/db/s/collection_sharding_state.cpp27
-rw-r--r--src/mongo/db/s/collection_sharding_state.h26
-rw-r--r--src/mongo/db/s/get_shard_version_command.cpp2
-rw-r--r--src/mongo/db/s/op_observer_sharding_impl.cpp1
-rw-r--r--src/mongo/db/s/shard_server_op_observer.cpp4
16 files changed, 168 insertions, 154 deletions
diff --git a/src/mongo/db/commands/count_cmd.cpp b/src/mongo/db/commands/count_cmd.cpp
index 50cd6752024..9a4fd7ff529 100644
--- a/src/mongo/db/commands/count_cmd.cpp
+++ b/src/mongo/db/commands/count_cmd.cpp
@@ -152,8 +152,7 @@ public:
// Prevent chunks from being cleaned up during yields - this allows us to only check the
// version on initial entry into count.
- auto rangePreserver =
- CollectionShardingState::get(opCtx, nss)->getMetadataForOperation(opCtx);
+ auto rangePreserver = CollectionShardingState::get(opCtx, nss)->getCurrentMetadata();
auto statusWithPlanExecutor =
getExecutorCount(opCtx, collection, request.getValue(), true /*explain*/);
@@ -206,8 +205,7 @@ public:
// Prevent chunks from being cleaned up during yields - this allows us to only check the
// version on initial entry into count.
- auto rangePreserver =
- CollectionShardingState::get(opCtx, nss)->getMetadataForOperation(opCtx);
+ auto rangePreserver = CollectionShardingState::get(opCtx, nss)->getCurrentMetadata();
auto statusWithPlanExecutor =
getExecutorCount(opCtx, collection, request.getValue(), false /*explain*/);
diff --git a/src/mongo/db/commands/geo_near_cmd.cpp b/src/mongo/db/commands/geo_near_cmd.cpp
index 336ce83ebba..e21ccc9860f 100644
--- a/src/mongo/db/commands/geo_near_cmd.cpp
+++ b/src/mongo/db/commands/geo_near_cmd.cpp
@@ -230,9 +230,9 @@ public:
unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue());
// Prevent chunks from being cleaned up during yields - this allows us to only check the
- // version on initial entry into geoNear.
- auto rangePreserver =
- CollectionShardingState::get(opCtx, nss)->getMetadataForOperation(opCtx);
+ // version on initial entry into geoNear (which happens as part of
+ // AutoGetCollectionForReadCommand).
+ auto rangePreserver = CollectionShardingState::get(opCtx, nss)->getCurrentMetadata();
const auto& readConcernArgs = repl::ReadConcernArgs::get(opCtx);
const PlanExecutor::YieldPolicy yieldPolicy =
diff --git a/src/mongo/db/commands/mr.cpp b/src/mongo/db/commands/mr.cpp
index 4a23c78b7fb..8d99882c92d 100644
--- a/src/mongo/db/commands/mr.cpp
+++ b/src/mongo/db/commands/mr.cpp
@@ -1434,7 +1434,7 @@ public:
const auto metadata = [&] {
AutoGetCollectionForReadCommand autoColl(opCtx, config.nss);
- return CollectionShardingState::get(opCtx, config.nss)->getMetadataForOperation(opCtx);
+ return CollectionShardingState::get(opCtx, config.nss)->getCurrentMetadata();
}();
bool shouldHaveData = false;
diff --git a/src/mongo/db/exec/update.cpp b/src/mongo/db/exec/update.cpp
index eb568bfb8e4..e2b78460b59 100644
--- a/src/mongo/db/exec/update.cpp
+++ b/src/mongo/db/exec/update.cpp
@@ -281,7 +281,6 @@ BSONObj UpdateStage::transformAndUpdate(const Snapshotted<BSONObj>& oldObj, Reco
}
if (docWasModified) {
-
// Prepare to write back the modified document
WriteUnitOfWork wunit(getOpCtx());
diff --git a/src/mongo/db/op_observer_impl.cpp b/src/mongo/db/op_observer_impl.cpp
index 15abf920fa6..62a6d9699cf 100644
--- a/src/mongo/db/op_observer_impl.cpp
+++ b/src/mongo/db/op_observer_impl.cpp
@@ -311,7 +311,7 @@ OpTimeBundle replLogApplyOps(OperationContext* opCtx,
BSONObj OpObserverImpl::getDocumentKey(OperationContext* opCtx,
NamespaceString const& nss,
BSONObj const& doc) {
- auto metadata = CollectionShardingState::get(opCtx, nss)->getMetadataForOperation(opCtx);
+ auto metadata = CollectionShardingState::get(opCtx, nss)->getCurrentMetadata();
return metadata->extractDocumentKey(doc).getOwned();
}
diff --git a/src/mongo/db/pipeline/pipeline_d.cpp b/src/mongo/db/pipeline/pipeline_d.cpp
index 9523261eb8a..5b368e81af1 100644
--- a/src/mongo/db/pipeline/pipeline_d.cpp
+++ b/src/mongo/db/pipeline/pipeline_d.cpp
@@ -157,7 +157,7 @@ StatusWith<unique_ptr<PlanExecutor, PlanExecutor::Deleter>> createRandomCursorEx
if (ShardingState::get(opCtx)->needCollectionMetadata(opCtx, collection->ns().ns())) {
auto shardFilterStage = stdx::make_unique<ShardFilterStage>(
opCtx,
- CollectionShardingState::get(opCtx, collection->ns())->getMetadataForOperation(opCtx),
+ CollectionShardingState::get(opCtx, collection->ns())->getOrphansFilter(opCtx),
ws.get(),
stage.release());
return PlanExecutor::make(opCtx,
diff --git a/src/mongo/db/query/get_executor.cpp b/src/mongo/db/query/get_executor.cpp
index defba5f3c69..ea89990bd2c 100644
--- a/src/mongo/db/query/get_executor.cpp
+++ b/src/mongo/db/query/get_executor.cpp
@@ -178,8 +178,8 @@ void fillOutPlannerParams(OperationContext* opCtx,
// If the caller wants a shard filter, make sure we're actually sharded.
if (plannerParams->options & QueryPlannerParams::INCLUDE_SHARD_FILTER) {
- auto collMetadata = CollectionShardingState::get(opCtx, canonicalQuery->nss())
- ->getMetadataForOperation(opCtx);
+ auto collMetadata =
+ CollectionShardingState::get(opCtx, canonicalQuery->nss())->getCurrentMetadata();
if (collMetadata->isSharded()) {
plannerParams->shardKey = collMetadata->getKeyPattern();
} else {
@@ -313,8 +313,7 @@ StatusWith<PrepareExecutionResult> prepareExecution(OperationContext* opCtx,
if (plannerParams.options & QueryPlannerParams::INCLUDE_SHARD_FILTER) {
root = make_unique<ShardFilterStage>(
opCtx,
- CollectionShardingState::get(opCtx, canonicalQuery->nss())
- ->getMetadataForOperation(opCtx),
+ CollectionShardingState::get(opCtx, canonicalQuery->nss())->getOrphansFilter(opCtx),
ws,
root.release());
}
diff --git a/src/mongo/db/query/stage_builder.cpp b/src/mongo/db/query/stage_builder.cpp
index c1390d0d18c..89a996be968 100644
--- a/src/mongo/db/query/stage_builder.cpp
+++ b/src/mongo/db/query/stage_builder.cpp
@@ -302,11 +302,11 @@ PlanStage* buildStages(OperationContext* opCtx,
if (nullptr == childStage) {
return nullptr;
}
- return new ShardFilterStage(opCtx,
- CollectionShardingState::get(opCtx, collection->ns())
- ->getMetadataForOperation(opCtx),
- ws,
- childStage);
+ return new ShardFilterStage(
+ opCtx,
+ CollectionShardingState::get(opCtx, collection->ns())->getOrphansFilter(opCtx),
+ ws,
+ childStage);
}
case STAGE_KEEP_MUTATIONS: {
const KeepMutationsNode* km = static_cast<const KeepMutationsNode*>(root);
diff --git a/src/mongo/db/s/collection_metadata.cpp b/src/mongo/db/s/collection_metadata.cpp
index 19c7b60a759..108395683d8 100644
--- a/src/mongo/db/s/collection_metadata.cpp
+++ b/src/mongo/db/s/collection_metadata.cpp
@@ -47,6 +47,46 @@ namespace mongo {
CollectionMetadata::CollectionMetadata(std::shared_ptr<ChunkManager> cm, const ShardId& thisShardId)
: _cm(std::move(cm)), _thisShardId(thisShardId) {}
+BSONObj CollectionMetadata::extractDocumentKey(const BSONObj& doc) const {
+ BSONObj key;
+
+ if (isSharded()) {
+ auto const& pattern = _cm->getShardKeyPattern();
+ key = dotted_path_support::extractElementsBasedOnTemplate(doc, pattern.toBSON());
+ if (pattern.hasId()) {
+ return key;
+ }
+ // else, try to append an _id field from the document.
+ }
+
+ if (auto id = doc["_id"]) {
+ return key.isEmpty() ? id.wrap() : BSONObjBuilder(std::move(key)).append(id).obj();
+ }
+
+ // For legacy documents that lack an _id, use the document itself as its key.
+ return doc;
+}
+
+void CollectionMetadata::toBSONBasic(BSONObjBuilder& bb) const {
+ if (isSharded()) {
+ _cm->getVersion().appendLegacyWithField(&bb, "collVersion");
+ getShardVersion().appendLegacyWithField(&bb, "shardVersion");
+ bb.append("keyPattern", _cm->getShardKeyPattern().toBSON());
+ } else {
+ ChunkVersion::UNSHARDED().appendLegacyWithField(&bb, "collVersion");
+ ChunkVersion::UNSHARDED().appendLegacyWithField(&bb, "shardVersion");
+ }
+}
+
+std::string CollectionMetadata::toStringBasic() const {
+ if (isSharded()) {
+ return str::stream() << "collection version: " << _cm->getVersion().toString()
+ << ", shard version: " << getShardVersion().toString();
+ } else {
+ return "collection version: <unsharded>";
+ }
+}
+
RangeMap CollectionMetadata::getChunks() const {
invariant(isSharded());
@@ -113,62 +153,8 @@ Status CollectionMetadata::checkChunkIsValid(const ChunkType& chunk) const {
return Status::OK();
}
-BSONObj CollectionMetadata::extractDocumentKey(BSONObj const& doc) const {
- BSONObj key;
-
- if (isSharded()) {
- auto const& pattern = getChunkManager()->getShardKeyPattern();
- key = dotted_path_support::extractElementsBasedOnTemplate(doc, pattern.toBSON());
- if (pattern.hasId()) {
- return key;
- }
- // else, try to append an _id field from the document.
- }
-
- if (auto id = doc["_id"]) {
- return key.isEmpty() ? id.wrap() : BSONObjBuilder(std::move(key)).append(id).obj();
- }
-
- // For legacy documents that lack an _id, use the document itself as its key.
- return doc;
-}
-
-void CollectionMetadata::toBSONBasic(BSONObjBuilder& bb) const {
- if (isSharded()) {
- _cm->getVersion().appendLegacyWithField(&bb, "collVersion");
- getShardVersion().appendLegacyWithField(&bb, "shardVersion");
- bb.append("keyPattern", _cm->getShardKeyPattern().toBSON());
- } else {
- ChunkVersion::UNSHARDED().appendLegacyWithField(&bb, "collVersion");
- ChunkVersion::UNSHARDED().appendLegacyWithField(&bb, "shardVersion");
- }
-}
-
-void CollectionMetadata::toBSONChunks(BSONArrayBuilder& bb) const {
- if (!isSharded())
- return;
-
- for (const auto& chunk : _cm->chunks()) {
- if (chunk.getShardId() == _thisShardId) {
- BSONArrayBuilder chunkBB(bb.subarrayStart());
- chunkBB.append(chunk.getMin());
- chunkBB.append(chunk.getMax());
- chunkBB.done();
- }
- }
-}
-
-std::string CollectionMetadata::toStringBasic() const {
- if (isSharded()) {
- return str::stream() << "collection version: " << _cm->getVersion().toString()
- << ", shard version: " << getShardVersion().toString();
- } else {
- return "collection version: <unsharded>";
- }
-}
-
boost::optional<ChunkRange> CollectionMetadata::getNextOrphanRange(
- RangeMap const& receivingChunks, BSONObj const& origLookupKey) const {
+ const RangeMap& receivingChunks, const BSONObj& origLookupKey) const {
invariant(isSharded());
const BSONObj maxKey = getMaxKey();
@@ -236,4 +222,18 @@ boost::optional<ChunkRange> CollectionMetadata::getNextOrphanRange(
return boost::none;
}
+void CollectionMetadata::toBSONChunks(BSONArrayBuilder* builder) const {
+ if (!isSharded())
+ return;
+
+ for (const auto& chunk : _cm->chunks()) {
+ if (chunk.getShardId() == _thisShardId) {
+ BSONArrayBuilder chunkBB(builder->subarrayStart());
+ chunkBB.append(chunk.getMin());
+ chunkBB.append(chunk.getMax());
+ chunkBB.done();
+ }
+ }
+}
+
} // namespace mongo
diff --git a/src/mongo/db/s/collection_metadata.h b/src/mongo/db/s/collection_metadata.h
index ae72682ca49..f123af36e26 100644
--- a/src/mongo/db/s/collection_metadata.h
+++ b/src/mongo/db/s/collection_metadata.h
@@ -64,8 +64,7 @@ public:
CollectionMetadata(std::shared_ptr<ChunkManager> cm, const ShardId& thisShardId);
/**
- * Returns whether this metadata object represents a sharded collection which requires
- * filtering.
+ * Returns whether this metadata object represents a sharded or unsharded collection.
*/
bool isSharded() const {
return bool(_cm);
@@ -86,6 +85,47 @@ public:
}
/**
+ * Obtains the shard id with which this collection metadata is configured.
+ */
+ const ShardId& shardId() const {
+ invariant(isSharded());
+ return _thisShardId;
+ }
+
+ /**
+ * Returns true if 'key' contains exactly the same fields as the shard key pattern.
+ */
+ bool isValidKey(const BSONObj& key) const {
+ invariant(isSharded());
+ return _cm->getShardKeyPattern().isShardKey(key);
+ }
+
+ const BSONObj& getKeyPattern() const {
+ invariant(isSharded());
+ return _cm->getShardKeyPattern().toBSON();
+ }
+
+ const std::vector<std::unique_ptr<FieldRef>>& getKeyPatternFields() const {
+ invariant(isSharded());
+ return _cm->getShardKeyPattern().getKeyPatternFields();
+ }
+
+ BSONObj getMinKey() const {
+ invariant(isSharded());
+ return _cm->getShardKeyPattern().getKeyPattern().globalMin();
+ }
+
+ BSONObj getMaxKey() const {
+ invariant(isSharded());
+ return _cm->getShardKeyPattern().getKeyPattern().globalMax();
+ }
+
+ bool uuidMatches(UUID uuid) const {
+ invariant(isSharded());
+ return _cm->uuidMatches(uuid);
+ }
+
+ /**
* Returns just the shard key fields, if the collection is sharded, and the _id field, from
* `doc`. Does not alter any field values (e.g. by hashing); values are copied verbatim.
*/
@@ -97,29 +137,17 @@ public:
void toBSONBasic(BSONObjBuilder& bb) const;
/**
- * BSON output of the chunks metadata into a BSONArray
- */
- void toBSONChunks(BSONArrayBuilder& bb) const;
-
- /**
* String output of the collection and shard versions.
*/
std::string toStringBasic() const;
- /**
- * Obtains the shard id with which this collection metadata is configured.
- */
- const ShardId& shardId() const {
- invariant(isSharded());
- return _thisShardId;
- }
+ //
+ // Methods used for orphan filtering and general introspection of the chunks owned by the shard
+ //
- /**
- * Returns true if 'key' contains exactly the same fields as the shard key pattern.
- */
- bool isValidKey(const BSONObj& key) const {
+ ChunkManager* getChunkManager() const {
invariant(isSharded());
- return _cm->getShardKeyPattern().isShardKey(key);
+ return _cm.get();
}
/**
@@ -152,7 +180,7 @@ public:
/**
* Returns true if the argument range overlaps any chunk.
*/
- bool rangeOverlapsChunk(ChunkRange const& range) const {
+ bool rangeOverlapsChunk(const ChunkRange& range) const {
invariant(isSharded());
return _cm->rangeOverlapsShard(range, _thisShardId);
}
@@ -175,49 +203,25 @@ public:
*
* @return orphanRange the output range. Note that the NS is not set.
*/
- boost::optional<ChunkRange> getNextOrphanRange(RangeMap const& receiveMap,
- BSONObj const& lookupKey) const;
+ boost::optional<ChunkRange> getNextOrphanRange(const RangeMap& receiveMap,
+ const BSONObj& lookupKey) const;
/**
* Returns all the chunks which are contained on this shard.
*/
RangeMap getChunks() const;
- const BSONObj& getKeyPattern() const {
- invariant(isSharded());
- return _cm->getShardKeyPattern().toBSON();
- }
-
- const std::vector<std::unique_ptr<FieldRef>>& getKeyPatternFields() const {
- invariant(isSharded());
- return _cm->getShardKeyPattern().getKeyPatternFields();
- }
-
- BSONObj getMinKey() const {
- invariant(isSharded());
- return _cm->getShardKeyPattern().getKeyPattern().globalMin();
- }
-
- BSONObj getMaxKey() const {
- invariant(isSharded());
- return _cm->getShardKeyPattern().getKeyPattern().globalMax();
- }
-
- std::shared_ptr<ChunkManager> getChunkManager() const {
- invariant(isSharded());
- return _cm;
- }
-
- bool uuidMatches(UUID uuid) const {
- invariant(isSharded());
- return _cm->uuidMatches(uuid);
- }
+ /**
+ * BSON output of the chunks metadata into a BSONArray
+ */
+ void toBSONChunks(BSONArrayBuilder* builder) const;
private:
- // The full routing table for the collection.
+ // The full routing table for the collection or nullptr if the collection is not sharded
std::shared_ptr<ChunkManager> _cm;
- // The identity of this shard, for the purpose of answering "key belongs to me" queries.
+ // The identity of this shard, for the purpose of answering "key belongs to me" queries. If the
+ // collection is not sharded (_cm is nullptr), then this value will be empty.
ShardId _thisShardId;
};
diff --git a/src/mongo/db/s/collection_metadata_filtering_test.cpp b/src/mongo/db/s/collection_metadata_filtering_test.cpp
index 46db156c36a..00c19583b17 100644
--- a/src/mongo/db/s/collection_metadata_filtering_test.cpp
+++ b/src/mongo/db/s/collection_metadata_filtering_test.cpp
@@ -141,7 +141,7 @@ TEST_F(CollectionMetadataFilteringTest, FilterDocumentsInTheFuture) {
AutoGetCollection autoColl(operationContext(), kNss, MODE_IS);
auto* const css = CollectionShardingState::get(operationContext(), kNss);
- testFn(css->getMetadataForOperation(operationContext()));
+ testFn(css->getOrphansFilter(operationContext()));
}
{
@@ -172,7 +172,7 @@ TEST_F(CollectionMetadataFilteringTest, FilterDocumentsInThePast) {
AutoGetCollection autoColl(operationContext(), kNss, MODE_IS);
auto* const css = CollectionShardingState::get(operationContext(), kNss);
- testFn(css->getMetadataForOperation(operationContext()));
+ testFn(css->getOrphansFilter(operationContext()));
}
{
@@ -211,7 +211,7 @@ TEST_F(CollectionMetadataFilteringTest, FilterDocumentsTooFarInThePastThrowsStal
AutoGetCollection autoColl(operationContext(), kNss, MODE_IS);
auto* const css = CollectionShardingState::get(operationContext(), kNss);
- testFn(css->getMetadataForOperation(operationContext()));
+ testFn(css->getOrphansFilter(operationContext()));
}
{
diff --git a/src/mongo/db/s/collection_sharding_state.cpp b/src/mongo/db/s/collection_sharding_state.cpp
index f65f262a029..8a3e0304146 100644
--- a/src/mongo/db/s/collection_sharding_state.cpp
+++ b/src/mongo/db/s/collection_sharding_state.cpp
@@ -111,7 +111,8 @@ private:
const auto kUnshardedCollection = std::make_shared<UnshardedCollection>();
-ChunkVersion getOperationReceivedVersion(OperationContext* opCtx, const NamespaceString& nss) {
+boost::optional<ChunkVersion> getOperationReceivedVersion(OperationContext* opCtx,
+ const NamespaceString& nss) {
auto& oss = OperationShardingState::get(opCtx);
// If there is a version attached to the OperationContext, use it as the received version,
@@ -125,12 +126,12 @@ ChunkVersion getOperationReceivedVersion(OperationContext* opCtx, const Namespac
// in a single call, the lack of version for a namespace on the collection must be treated
// as UNSHARDED
return connectionShardVersion.value_or(ChunkVersion::UNSHARDED());
- } else {
- // There is no shard version information on either 'opCtx' or 'client'. This means that the
- // operation represented by 'opCtx' is unversioned, and the shard version is always OK for
- // unversioned operations.
- return ChunkVersion::IGNORED();
}
+
+ // There is no shard version information on either 'opCtx' or 'client'. This means that the
+ // operation represented by 'opCtx' is unversioned, and the shard version is always OK for
+ // unversioned operations
+ return boost::none;
}
} // namespace
@@ -151,12 +152,10 @@ void CollectionShardingState::report(OperationContext* opCtx, BSONObjBuilder* bu
collectionsMap->report(opCtx, builder);
}
-ScopedCollectionMetadata CollectionShardingState::getMetadataForOperation(OperationContext* opCtx) {
+ScopedCollectionMetadata CollectionShardingState::getOrphansFilter(OperationContext* opCtx) {
const auto receivedShardVersion = getOperationReceivedVersion(opCtx, _nss);
-
- if (ChunkVersion::isIgnoredVersion(receivedShardVersion)) {
+ if (!receivedShardVersion)
return {kUnshardedCollection};
- }
const auto atClusterTime = repl::ReadConcernArgs::get(opCtx).getArgsAtClusterTime();
auto optMetadata = _getMetadata(atClusterTime);
@@ -193,8 +192,12 @@ boost::optional<ChunkVersion> CollectionShardingState::getCurrentShardVersionIfK
}
void CollectionShardingState::checkShardVersionOrThrow(OperationContext* opCtx) {
- const auto receivedShardVersion = getOperationReceivedVersion(opCtx, _nss);
+ const auto optReceivedShardVersion = getOperationReceivedVersion(opCtx, _nss);
+
+ if (!optReceivedShardVersion)
+ return;
+ const auto& receivedShardVersion = *optReceivedShardVersion;
if (ChunkVersion::isIgnoredVersion(receivedShardVersion)) {
return;
}
@@ -203,7 +206,7 @@ void CollectionShardingState::checkShardVersionOrThrow(OperationContext* opCtx)
invariant(repl::ReadConcernArgs::get(opCtx).getLevel() !=
repl::ReadConcernLevel::kAvailableReadConcern);
- const auto metadata = getMetadataForOperation(opCtx);
+ const auto metadata = getCurrentMetadata();
const auto wantedShardVersion =
metadata->isSharded() ? metadata->getShardVersion() : ChunkVersion::UNSHARDED();
diff --git a/src/mongo/db/s/collection_sharding_state.h b/src/mongo/db/s/collection_sharding_state.h
index e964dbced12..cbd7f9d563f 100644
--- a/src/mongo/db/s/collection_sharding_state.h
+++ b/src/mongo/db/s/collection_sharding_state.h
@@ -73,16 +73,26 @@ public:
static void report(OperationContext* opCtx, BSONObjBuilder* builder);
/**
- * Returns the chunk filtering metadata that the current operation should be using for that
- * collection or otherwise throws if it has not been loaded yet. If the operation does not
- * require a specific shard version, returns an UNSHARDED metadata. The returned object is safe
- * to access outside of collection lock.
+ * Returns the orphan chunk filtering metadata that the current operation should be using for
+ * the collection.
*
- * If the operation context contains an 'atClusterTime' property, the returned filtering
- * metadata will be tied to a specific point in time. Otherwise it will reference the latest
- * time available.
+ * If the operation context contains an 'atClusterTime', the returned filtering metadata will be
+ * tied to a specific point in time. Otherwise, it will reference the latest time available. If
+ * the operation is not associated with a shard version (refer to
+ * OperationShardingState::isOperationVersioned for more info on that), returns an UNSHARDED
+ * metadata object.
+ *
+ * The intended users of this method are callers which need to perform orphan filtering. Use
+ * 'getCurrentMetadata' for all other cases, where just sharding-related properties of the
+ * collection are necessary (e.g., isSharded or the shard key).
+ *
+ * The returned object is safe to access even after the collection lock has been dropped.
+ */
+ ScopedCollectionMetadata getOrphansFilter(OperationContext* opCtx);
+
+ /**
+ * See the comments for 'getOrphansFilter' above for more information on this method.
*/
- ScopedCollectionMetadata getMetadataForOperation(OperationContext* opCtx);
ScopedCollectionMetadata getCurrentMetadata();
/**
diff --git a/src/mongo/db/s/get_shard_version_command.cpp b/src/mongo/db/s/get_shard_version_command.cpp
index a51ce749549..b986ffecb82 100644
--- a/src/mongo/db/s/get_shard_version_command.cpp
+++ b/src/mongo/db/s/get_shard_version_command.cpp
@@ -133,7 +133,7 @@ public:
metadata->toBSONBasic(metadataBuilder);
BSONArrayBuilder chunksArr(metadataBuilder.subarrayStart("chunks"));
- metadata->toBSONChunks(chunksArr);
+ metadata->toBSONChunks(&chunksArr);
chunksArr.doneFast();
BSONArrayBuilder pendingArr(metadataBuilder.subarrayStart("pending"));
diff --git a/src/mongo/db/s/op_observer_sharding_impl.cpp b/src/mongo/db/s/op_observer_sharding_impl.cpp
index 0f6aaba48c4..70b090881de 100644
--- a/src/mongo/db/s/op_observer_sharding_impl.cpp
+++ b/src/mongo/db/s/op_observer_sharding_impl.cpp
@@ -63,6 +63,7 @@
namespace mongo {
namespace {
+
const auto getIsMigrating = OperationContext::declareDecoration<bool>();
}
diff --git a/src/mongo/db/s/shard_server_op_observer.cpp b/src/mongo/db/s/shard_server_op_observer.cpp
index 3078fd59396..5733763902c 100644
--- a/src/mongo/db/s/shard_server_op_observer.cpp
+++ b/src/mongo/db/s/shard_server_op_observer.cpp
@@ -207,7 +207,7 @@ void ShardServerOpObserver::onInserts(OperationContext* opCtx,
std::vector<InsertStatement>::const_iterator end,
bool fromMigrate) {
auto* const css = CollectionShardingState::get(opCtx, nss);
- const auto metadata = css->getMetadataForOperation(opCtx);
+ const auto metadata = css->getCurrentMetadata();
for (auto it = begin; it != end; ++it) {
const auto& insertedDoc = it->doc;
@@ -233,7 +233,7 @@ void ShardServerOpObserver::onInserts(OperationContext* opCtx,
void ShardServerOpObserver::onUpdate(OperationContext* opCtx, const OplogUpdateEntryArgs& args) {
auto* const css = CollectionShardingState::get(opCtx, args.nss);
- const auto metadata = css->getMetadataForOperation(opCtx);
+ const auto metadata = css->getCurrentMetadata();
if (args.nss == NamespaceString::kShardConfigCollectionsNamespace) {
// Notification of routing table changes are only needed on secondaries