diff options
author | Sergi Mateo Bellido <sergi.mateo-bellido@mongodb.com> | 2023-05-08 06:26:40 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2023-05-08 07:22:47 +0000 |
commit | 73013a50d60d58c9525df3e1e5b3c6ace21cb7f6 (patch) | |
tree | b10a7a0a1a162d3f07c978227d89863a37933c10 /src/mongo | |
parent | 207c65e39a06e0b00b73e56ae6c41cb17d89d8a4 (diff) | |
download | mongo-73013a50d60d58c9525df3e1e5b3c6ace21cb7f6.tar.gz |
SERVER-76489 Fixing implicit create collection on sharded DDL ops
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/cloner.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/s/implicit_collection_creation_test.cpp | 21 | ||||
-rw-r--r-- | src/mongo/db/s/migration_destination_manager.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/s/operation_sharding_state.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/s/operation_sharding_state.h | 13 | ||||
-rw-r--r-- | src/mongo/db/s/shard_server_op_observer.cpp | 7 |
6 files changed, 44 insertions, 9 deletions
diff --git a/src/mongo/db/cloner.cpp b/src/mongo/db/cloner.cpp index c3aae94fd88..68c683385e2 100644 --- a/src/mongo/db/cloner.cpp +++ b/src/mongo/db/cloner.cpp @@ -418,7 +418,8 @@ Status DefaultClonerImpl::_createCollectionsForDb( { OperationShardingState::ScopedAllowImplicitCollectionCreate_UNSAFE - unsafeCreateCollection(opCtx); + unsafeCreateCollection(opCtx, + /* forceCSRAsUnknownAfterCollectionCreation */ true); Status createStatus = db->userCreateNS( opCtx, nss, collectionOptions, createDefaultIndexes, params.idIndexSpec); if (!createStatus.isOK()) { diff --git a/src/mongo/db/s/implicit_collection_creation_test.cpp b/src/mongo/db/s/implicit_collection_creation_test.cpp index ae1016e4644..a7957a225c6 100644 --- a/src/mongo/db/s/implicit_collection_creation_test.cpp +++ b/src/mongo/db/s/implicit_collection_creation_test.cpp @@ -31,6 +31,7 @@ #include "mongo/platform/basic.h" #include "mongo/db/catalog_raii.h" +#include "mongo/db/s/collection_sharding_runtime.h" #include "mongo/db/s/operation_sharding_state.h" #include "mongo/db/s/shard_server_test_fixture.h" #include "mongo/unittest/unittest.h" @@ -66,6 +67,26 @@ TEST_F(ImplicitCollectionCreationTest, AllowImplicitCollectionCreate) { WriteUnitOfWork wuow(operationContext()); ASSERT_OK(db->userCreateNS(operationContext(), nss, CollectionOptions{})); wuow.commit(); + + const auto scopedCsr = + CollectionShardingRuntime::assertCollectionLockedAndAcquireShared(operationContext(), nss); + ASSERT_TRUE(scopedCsr->getCurrentMetadataIfKnown()); +} + +TEST_F(ImplicitCollectionCreationTest, AllowImplicitCollectionCreateWithSetCSRAsUnknown) { + NamespaceString nss = + NamespaceString::createNamespaceString_forTest("AllowImplicitCollectionCreateDB.TestColl"); + OperationShardingState::ScopedAllowImplicitCollectionCreate_UNSAFE unsafeCreateCollection( + operationContext(), /* forceCSRAsUnknownAfterCollectionCreation */ true); + AutoGetCollection autoColl(operationContext(), nss, MODE_IX); + auto db = autoColl.ensureDbExists(operationContext()); + WriteUnitOfWork wuow(operationContext()); + ASSERT_OK(db->userCreateNS(operationContext(), nss, CollectionOptions{})); + wuow.commit(); + + const auto scopedCsr = + CollectionShardingRuntime::assertCollectionLockedAndAcquireShared(operationContext(), nss); + ASSERT_FALSE(scopedCsr->getCurrentMetadataIfKnown()); } } // namespace diff --git a/src/mongo/db/s/migration_destination_manager.cpp b/src/mongo/db/s/migration_destination_manager.cpp index 47558dbb88a..9210fc9cc2c 100644 --- a/src/mongo/db/s/migration_destination_manager.cpp +++ b/src/mongo/db/s/migration_destination_manager.cpp @@ -1058,10 +1058,9 @@ void MigrationDestinationManager::cloneCollectionIndexesAndOptions( << collectionByUUID->ns().toStringForErrorMsg()); } - // We do not have a collection by this name. Create the collection with the donor's - // options. + // We do not have a collection by this name. Create it with the donor's options. OperationShardingState::ScopedAllowImplicitCollectionCreate_UNSAFE - unsafeCreateCollection(opCtx); + unsafeCreateCollection(opCtx, /* forceCSRAsUnknownAfterCollectionCreation */ true); WriteUnitOfWork wuow(opCtx); CollectionOptions collectionOptions = uassertStatusOK( CollectionOptions::parse(collectionOptionsAndIndexes.options, diff --git a/src/mongo/db/s/operation_sharding_state.cpp b/src/mongo/db/s/operation_sharding_state.cpp index 1c6d9bf94f5..cd34b05f8a8 100644 --- a/src/mongo/db/s/operation_sharding_state.cpp +++ b/src/mongo/db/s/operation_sharding_state.cpp @@ -169,17 +169,19 @@ using ScopedAllowImplicitCollectionCreate_UNSAFE = OperationShardingState::ScopedAllowImplicitCollectionCreate_UNSAFE; ScopedAllowImplicitCollectionCreate_UNSAFE::ScopedAllowImplicitCollectionCreate_UNSAFE( - OperationContext* opCtx) + OperationContext* opCtx, bool forceCSRAsUnknownAfterCollectionCreation) : _opCtx(opCtx) { auto& oss = get(_opCtx); invariant(!oss._allowCollectionCreation); oss._allowCollectionCreation = true; + oss._forceCSRAsUnknownAfterCollectionCreation = forceCSRAsUnknownAfterCollectionCreation; } ScopedAllowImplicitCollectionCreate_UNSAFE::~ScopedAllowImplicitCollectionCreate_UNSAFE() { auto& oss = get(_opCtx); invariant(oss._allowCollectionCreation); oss._allowCollectionCreation = false; + oss._forceCSRAsUnknownAfterCollectionCreation = false; } ScopedSetShardRole::ScopedSetShardRole(OperationContext* opCtx, diff --git a/src/mongo/db/s/operation_sharding_state.h b/src/mongo/db/s/operation_sharding_state.h index baf7fc62214..05e3533941e 100644 --- a/src/mongo/db/s/operation_sharding_state.h +++ b/src/mongo/db/s/operation_sharding_state.h @@ -96,11 +96,17 @@ public: * * Instantiating this object on the stack indicates to the storage execution subsystem that it * is allowed to create any collection in this context and that the caller will be responsible - * for notifying the shard Sharding sybsystem of the collection creation. + * for notifying the shard Sharding subsystem of the collection creation. Note that in most of + * cases the CollectionShardingRuntime associated to that nss will be set as UNSHARDED. However, + * there are some scenarios in which it is required to set is as UNKNOWN: that's the reason why + * the constructor has the 'forceCSRAsUnknownAfterCollectionCreation' parameter. You can find + * more information about how the CSR is modified in ShardServerOpObserver::onCreateCollection. */ class ScopedAllowImplicitCollectionCreate_UNSAFE { public: - ScopedAllowImplicitCollectionCreate_UNSAFE(OperationContext* opCtx); + /* Please read the comment associated to this class */ + ScopedAllowImplicitCollectionCreate_UNSAFE( + OperationContext* opCtx, bool forceCSRAsUnknownAfterCollectionCreation = false); ~ScopedAllowImplicitCollectionCreate_UNSAFE(); private: @@ -170,6 +176,9 @@ private: // Specifies whether the request is allowed to create database/collection implicitly bool _allowCollectionCreation{false}; + // Specifies whether the CollectionShardingRuntime should be set as unknown after collection + // creation + bool _forceCSRAsUnknownAfterCollectionCreation{false}; // Stores the shard version expected for each collection that will be accessed struct ShardVersionTracker { diff --git a/src/mongo/db/s/shard_server_op_observer.cpp b/src/mongo/db/s/shard_server_op_observer.cpp index 417ef53acd9..d324610decc 100644 --- a/src/mongo/db/s/shard_server_op_observer.cpp +++ b/src/mongo/db/s/shard_server_op_observer.cpp @@ -709,6 +709,7 @@ void ShardServerOpObserver::onCreateCollection(OperationContext* opCtx, const OplogSlot& createOpTime, bool fromMigrate) { // Only the shard primay nodes control the collection creation and secondaries just follow + // Secondaries CSR will be the defaulted one (UNKNOWN in most of the cases) if (!opCtx->writesAreReplicated()) { return; } @@ -733,10 +734,12 @@ void ShardServerOpObserver::onCreateCollection(OperationContext* opCtx, oss._allowCollectionCreation); // If the check above passes, this means the collection doesn't exist and is being created and - // that the caller will be responsible to eventially set the proper placement version + // that the caller will be responsible to eventially set the proper placement version. auto scopedCsr = CollectionShardingRuntime::assertCollectionLockedAndAcquireExclusive(opCtx, collectionName); - if (!scopedCsr->getCurrentMetadataIfKnown()) { + if (oss._forceCSRAsUnknownAfterCollectionCreation) { + scopedCsr->clearFilteringMetadata(opCtx); + } else if (!scopedCsr->getCurrentMetadataIfKnown()) { scopedCsr->setFilteringMetadata(opCtx, CollectionMetadata()); } } |