summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/pipeline_d.cpp
diff options
context:
space:
mode:
authorBernard Gorman <bernard.gorman@gmail.com>2018-11-13 14:44:57 +0000
committerBernard Gorman <bernard.gorman@gmail.com>2018-11-20 22:41:44 +0000
commit072f6a59fe9ae19b77507a550c50b973ef3124d2 (patch)
treef8bb1eb2a2731ecbc02adadbe1ed209aa2c33bc9 /src/mongo/db/pipeline/pipeline_d.cpp
parentae4011cf301665046c435c18fd6ef088f5881e04 (diff)
downloadmongo-072f6a59fe9ae19b77507a550c50b973ef3124d2.tar.gz
SERVER-37750 Optimized $sample stage does not yield
(cherry picked from commit 4177d6d22ab3329a8607bf80a62aa03d4fb2c528)
Diffstat (limited to 'src/mongo/db/pipeline/pipeline_d.cpp')
-rw-r--r--src/mongo/db/pipeline/pipeline_d.cpp32
1 files changed, 16 insertions, 16 deletions
diff --git a/src/mongo/db/pipeline/pipeline_d.cpp b/src/mongo/db/pipeline/pipeline_d.cpp
index 9d49b4ef6cd..9be12b669e6 100644
--- a/src/mongo/db/pipeline/pipeline_d.cpp
+++ b/src/mongo/db/pipeline/pipeline_d.cpp
@@ -455,6 +455,10 @@ private:
*/
StatusWith<unique_ptr<PlanExecutor, PlanExecutor::Deleter>> createRandomCursorExecutor(
Collection* collection, OperationContext* opCtx, long long sampleSize, long long numRecords) {
+ // Verify that we are already under a collection lock. We avoid taking locks ourselves in this
+ // function because double-locking forces any PlanExecutor we create to adopt a NO_YIELD policy.
+ invariant(opCtx->lockState()->isCollectionLockedForMode(collection->ns().ns(), MODE_IS));
+
double kMaxSampleRatioForRandCursor = 0.05;
if (sampleSize > numRecords * kMaxSampleRatioForRandCursor || numRecords <= 100) {
return {nullptr};
@@ -499,22 +503,18 @@ StatusWith<unique_ptr<PlanExecutor, PlanExecutor::Deleter>> createRandomCursorEx
opCtx, ws.get(), idxIterator.release(), nullptr, collection);
}
- {
- AutoGetCollectionForRead autoColl(opCtx, collection->ns());
-
- // If we're in a sharded environment, we need to filter out documents we don't own.
- if (ShardingState::get(opCtx)->needCollectionMetadata(opCtx, collection->ns().ns())) {
- auto shardFilterStage = stdx::make_unique<ShardFilterStage>(
- opCtx,
- CollectionShardingState::get(opCtx, collection->ns())->getMetadata(),
- ws.get(),
- stage.release());
- return PlanExecutor::make(opCtx,
- std::move(ws),
- std::move(shardFilterStage),
- collection,
- PlanExecutor::YIELD_AUTO);
- }
+ // If we're in a sharded environment, we need to filter out documents we don't own.
+ if (ShardingState::get(opCtx)->needCollectionMetadata(opCtx, collection->ns().ns())) {
+ auto shardFilterStage = stdx::make_unique<ShardFilterStage>(
+ opCtx,
+ CollectionShardingState::get(opCtx, collection->ns())->getMetadata(),
+ ws.get(),
+ stage.release());
+ return PlanExecutor::make(opCtx,
+ std::move(ws),
+ std::move(shardFilterStage),
+ collection,
+ PlanExecutor::YIELD_AUTO);
}
return PlanExecutor::make(