diff options
author | Bernard Gorman <bernard.gorman@gmail.com> | 2018-11-13 14:44:57 +0000 |
---|---|---|
committer | Bernard Gorman <bernard.gorman@gmail.com> | 2018-11-20 22:41:44 +0000 |
commit | 072f6a59fe9ae19b77507a550c50b973ef3124d2 (patch) | |
tree | f8bb1eb2a2731ecbc02adadbe1ed209aa2c33bc9 /src/mongo/db/pipeline/pipeline_d.cpp | |
parent | ae4011cf301665046c435c18fd6ef088f5881e04 (diff) | |
download | mongo-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.cpp | 32 |
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( |