diff options
author | Pierlauro Sciarelli <pierlauro.sciarelli@mongodb.com> | 2022-08-12 11:03:48 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-08-18 08:15:49 +0000 |
commit | 506c10404af0030d7fd6022ba76d34b5ad01cbae (patch) | |
tree | 3cee01cd9c49a219faa2dffdbf63e81fe37ebcf9 /src/mongo | |
parent | 8b2300fef3a91561de9410e1151097d87f046784 (diff) | |
download | mongo-506c10404af0030d7fd6022ba76d34b5ad01cbae.tar.gz |
SERVER-67385 Range deletion tasks on primary must not be scheduled before ongoing queries finish
(cherry picked from commit 32c2f632eaa7bf80607880162ec5e4eaeb22d7fe)
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/s/collection_sharding_runtime.cpp | 13 | ||||
-rw-r--r-- | src/mongo/db/s/collection_sharding_runtime.h | 22 | ||||
-rw-r--r-- | src/mongo/db/s/collection_sharding_runtime_test.cpp | 38 |
3 files changed, 64 insertions, 9 deletions
diff --git a/src/mongo/db/s/collection_sharding_runtime.cpp b/src/mongo/db/s/collection_sharding_runtime.cpp index 91a8d3d6090..8334f99b74b 100644 --- a/src/mongo/db/s/collection_sharding_runtime.cpp +++ b/src/mongo/db/s/collection_sharding_runtime.cpp @@ -211,9 +211,11 @@ void CollectionShardingRuntime::setFilteringMetadata_withLock(OperationContext* _metadataType = MetadataType::kUnsharded; _metadataManager.reset(); ++_numMetadataManagerChanges; - } else if (!_metadataManager || - !newMetadata.uuidMatches(_metadataManager->getCollectionUuid())) { - _metadataType = MetadataType::kSharded; + return; + } + + _metadataType = MetadataType::kSharded; + if (!_metadataManager || !newMetadata.uuidMatches(_metadataManager->getCollectionUuid())) { _metadataManager = std::make_shared<MetadataManager>( opCtx->getServiceContext(), _nss, _rangeDeleterExecutor, newMetadata); ++_numMetadataManagerChanges; @@ -236,7 +238,6 @@ void CollectionShardingRuntime::clearFilteringMetadata(OperationContext* opCtx) "Clearing collection metadata", "namespace"_attr = _nss); _metadataType = MetadataType::kUnknown; - _metadataManager.reset(); } } @@ -263,7 +264,7 @@ Status CollectionShardingRuntime::waitForClean(OperationContext* opCtx, // If the metadata was reset, or the collection was dropped and recreated since the // metadata manager was created, return an error. - if (!self->_metadataManager || + if (self->_metadataType != MetadataType::kSharded || (collectionUuid != self->_metadataManager->getCollectionUuid())) { return {ErrorCodes::ConflictingOperationInProgress, "Collection being migrated was dropped and created or otherwise had its " @@ -421,7 +422,7 @@ void CollectionShardingRuntime::appendShardVersion(BSONObjBuilder* builder) { size_t CollectionShardingRuntime::numberOfRangesScheduledForDeletion() const { stdx::lock_guard lk(_metadataManagerLock); - if (_metadataManager) { + if (_metadataType == MetadataType::kSharded) { return _metadataManager->numberOfRangesScheduledForDeletion(); } return 0; diff --git a/src/mongo/db/s/collection_sharding_runtime.h b/src/mongo/db/s/collection_sharding_runtime.h index 76954af1b61..d97deb9bee6 100644 --- a/src/mongo/db/s/collection_sharding_runtime.h +++ b/src/mongo/db/s/collection_sharding_runtime.h @@ -273,10 +273,26 @@ private: // Tracks whether the filtering metadata is unknown, unsharded, or sharded enum class MetadataType { kUnknown, kUnsharded, kSharded } _metadataType; - // If the collection is sharded, contains all the metadata associated with this collection. + // If the collection state is known and is unsharded, this will be nullptr. // - // If the collection is unsharded, the metadata has not been set yet, or the metadata has been - // specifically reset by calling clearFilteringMetadata(), this will be nullptr; + // If the collection state is known and is sharded, this will point to the metadata associated + // with this collection. + // + // If the collection state is unknown: + // - If the metadata had never been set yet, this will be nullptr. + // - If the collection state was known and was sharded, this contains the metadata that + // were known for the collection before the last invocation of clearFilteringMetadata(). + // + // The following matrix enumerates the valid (Y) and invalid (X) scenarios. + // _________________________________ + // | _metadataType (collection state)| + // |_________________________________| + // | UNKNOWN | UNSHARDED | SHARDED | + // _______________________|_________|___________|___________| + // |_metadataManager unset | Y | Y | X | + // |_______________________|_________|___________|___________| + // |_metadataManager set | Y | X | Y | + // |_______________________|_________|___________|___________| std::shared_ptr<MetadataManager> _metadataManager; // Used for testing to check the number of times a new MetadataManager has been installed. diff --git a/src/mongo/db/s/collection_sharding_runtime_test.cpp b/src/mongo/db/s/collection_sharding_runtime_test.cpp index dcee5b73ac0..79c72ef2436 100644 --- a/src/mongo/db/s/collection_sharding_runtime_test.cpp +++ b/src/mongo/db/s/collection_sharding_runtime_test.cpp @@ -539,5 +539,43 @@ TEST_F(CollectionShardingRuntimeWithRangeDeleterTest, ASSERT(cleanupComplete.isReady()); } +TEST_F(CollectionShardingRuntimeWithRangeDeleterTest, + WaitForCleanCorrectEvenAfterClearFollowedBySetFilteringMetadata) { + globalFailPointRegistry().find("suspendRangeDeletion")->setMode(FailPoint::alwaysOn); + ScopeGuard resetFailPoint( + [=] { globalFailPointRegistry().find("suspendRangeDeletion")->setMode(FailPoint::off); }); + + OperationContext* opCtx = operationContext(); + auto metadata = makeShardedMetadata(opCtx, uuid()); + csr().setFilteringMetadata(opCtx, metadata); + const ChunkRange range = ChunkRange(BSON(kShardKey << MINKEY), BSON(kShardKey << MAXKEY)); + const auto task = insertRangeDeletionTask(opCtx, kTestNss, uuid(), range, 0); + + // Schedule range deletion that will hang due to `suspendRangeDeletion` failpoint + auto cleanupComplete = + csr().cleanUpRange(range, task.getId(), CollectionShardingRuntime::CleanWhen::kNow); + + // Clear and set again filtering metadata + csr().clearFilteringMetadata(opCtx); + csr().setFilteringMetadata(opCtx, metadata); + + auto waitForCleanUp = [&](Date_t timeout) { + return CollectionShardingRuntime::waitForClean(opCtx, kTestNss, uuid(), range, timeout); + }; + + // Check that the hanging range deletion is still tracked even following a clear of the metadata + auto status = waitForCleanUp(Date_t::now() + Milliseconds(100)); + ASSERT_NOT_OK(status); + ASSERT(!cleanupComplete.isReady()); + + globalFailPointRegistry().find("suspendRangeDeletion")->setMode(FailPoint::off); + resetFailPoint.dismiss(); + + // Check that the range deletion is not tracked anymore after it succeeds + status = waitForCleanUp(Date_t::max()); + ASSERT_OK(status); + ASSERT(cleanupComplete.isReady()); +} + } // namespace } // namespace mongo |