diff --git a/src/mongo/db/index/index_access_method_test.cpp b/src/mongo/db/index/index_access_method_test.cpp index 59a1f3b3114..d00546b020b 100644 --- a/src/mongo/db/index/index_access_method_test.cpp +++ b/src/mongo/db/index/index_access_method_test.cpp @@ -44,11 +44,11 @@ #include "mongo/db/service_context.h" #include "mongo/db/service_context_d_test_fixture.h" #include "mongo/db/shard_role/lock_manager/lock_manager_defs.h" -#include "mongo/db/shard_role/shard_catalog/catalog_raii.h" #include "mongo/db/shard_role/shard_catalog/collection.h" #include "mongo/db/shard_role/shard_catalog/index_catalog.h" #include "mongo/db/shard_role/shard_catalog/index_catalog_entry.h" #include "mongo/db/shard_role/shard_catalog/index_descriptor.h" +#include "mongo/db/shard_role/shard_role.h" #include "mongo/db/shard_role/transaction_resources.h" #include "mongo/db/storage/key_string/key_string.h" #include "mongo/unittest/unittest.h" @@ -248,8 +248,11 @@ TEST_F(IndexAccessMethodInsertKeys, DuplicatesCheckingOnSecondaryUniqueIndexes) << static_cast(IndexDescriptor::IndexVersion::kV2)); ASSERT_OK(createIndexFromSpec(opCtx, nss.ns_forTest(), indexSpec)); - AutoGetCollection autoColl(opCtx, nss, LockMode::MODE_X); - const auto& coll = *autoColl; + auto acq = acquireCollection( + opCtx, + CollectionAcquisitionRequest::fromOpCtx(opCtx, nss, AcquisitionPrerequisites::kWrite), + LockMode::MODE_X); + const auto& coll = acq.getCollectionPtr(); auto indexEntry = coll->getIndexCatalog()->findIndexByName(opCtx, indexName); auto indexAccessMethod = indexEntry->accessMethod()->asSortedData(); @@ -291,8 +294,11 @@ TEST_F(IndexAccessMethodInsertKeys, InsertWhenPrepareUnique) { << "v" << static_cast(IndexDescriptor::IndexVersion::kV2)); ASSERT_OK(createIndexFromSpec(opCtx, nss.ns_forTest(), indexSpec)); - AutoGetCollection autoColl(opCtx, nss, LockMode::MODE_X); - const auto& coll = *autoColl; + auto acq = acquireCollection( + opCtx, + CollectionAcquisitionRequest::fromOpCtx(opCtx, nss, AcquisitionPrerequisites::kWrite), + LockMode::MODE_X); + const auto& coll = acq.getCollectionPtr(); auto indexEntry = coll->getIndexCatalog()->findIndexByName(opCtx, indexName); auto indexAccessMethod = indexEntry->accessMethod()->asSortedData(); @@ -327,8 +333,11 @@ TEST_F(IndexAccessMethodUpdateKeys, UpdateWhenPrepareUnique) { << "v" << static_cast(IndexDescriptor::IndexVersion::kV2)); ASSERT_OK(createIndexFromSpec(opCtx, nss.ns_forTest(), indexSpec)); - AutoGetCollection autoColl(opCtx, nss, LockMode::MODE_X); - const auto& coll = *autoColl; + auto acq = acquireCollection( + opCtx, + CollectionAcquisitionRequest::fromOpCtx(opCtx, nss, AcquisitionPrerequisites::kWrite), + LockMode::MODE_X); + const auto& coll = acq.getCollectionPtr(); auto indexEntry = coll->getIndexCatalog()->findIndexByName(opCtx, indexName); auto indexAccessMethod = indexEntry->accessMethod()->asSortedData(); @@ -380,8 +389,11 @@ TEST_F(IndexAccessMethodBulkBuilder, CommitRejectsZeroInterval) { << static_cast(IndexDescriptor::IndexVersion::kV2)); ASSERT_OK(createIndexFromSpec(opCtx, nss.ns_forTest(), indexSpec)); - AutoGetCollection autoColl(opCtx, nss, LockMode::MODE_X); - const auto& coll = *autoColl; + auto acq = acquireCollection( + opCtx, + CollectionAcquisitionRequest::fromOpCtx(opCtx, nss, AcquisitionPrerequisites::kWrite), + LockMode::MODE_X); + const auto& coll = acq.getCollectionPtr(); auto indexEntry = coll->getIndexCatalog()->findIndexByName(opCtx, indexName); auto indexAccessMethod = indexEntry->accessMethod()->asSortedData(); diff --git a/src/mongo/db/index_builds/index_build_entry_helpers_test.cpp b/src/mongo/db/index_builds/index_build_entry_helpers_test.cpp index 159e15dd883..5f816711ace 100644 --- a/src/mongo/db/index_builds/index_build_entry_helpers_test.cpp +++ b/src/mongo/db/index_builds/index_build_entry_helpers_test.cpp @@ -39,8 +39,8 @@ #include "mongo/db/namespace_string.h" #include "mongo/db/operation_context.h" #include "mongo/db/shard_role/lock_manager/lock_manager_defs.h" -#include "mongo/db/shard_role/shard_catalog/catalog_raii.h" #include "mongo/db/shard_role/shard_catalog/catalog_test_fixture.h" +#include "mongo/db/shard_role/shard_role.h" #include "mongo/unittest/unittest.h" #include "mongo/util/net/hostandport.h" #include "mongo/util/uuid.h" @@ -99,8 +99,13 @@ void checkIfEqual(IndexBuildEntry lhs, IndexBuildEntry rhs) { } Status removeIndexBuildEntry(OperationContext* opCtx, UUID indexBuildUUID) { - AutoGetCollection autoColl(opCtx, NamespaceString::kIndexBuildEntryNamespace, MODE_IX); - return indexbuildentryhelpers::removeIndexBuildEntry(opCtx, *autoColl, indexBuildUUID); + auto acq = acquireCollection( + opCtx, + CollectionAcquisitionRequest::fromOpCtx( + opCtx, NamespaceString::kIndexBuildEntryNamespace, AcquisitionPrerequisites::kWrite), + MODE_IX); + return indexbuildentryhelpers::removeIndexBuildEntry( + opCtx, acq.getCollectionPtr(), indexBuildUUID); } class IndexBuildEntryHelpersTest : public CatalogTestFixture { diff --git a/src/mongo/db/index_builds/index_build_interceptor_test.cpp b/src/mongo/db/index_builds/index_build_interceptor_test.cpp index 330ce5ff993..0a241765b6f 100644 --- a/src/mongo/db/index_builds/index_build_interceptor_test.cpp +++ b/src/mongo/db/index_builds/index_build_interceptor_test.cpp @@ -95,7 +95,7 @@ class IndexBuilderInterceptorTest : public CatalogTestFixture { protected: const IndexCatalogEntry* createIndex(BSONObj spec) { WriteUnitOfWork wuow(operationContext()); - CollectionWriter writer{operationContext(), _coll.get()}; + CollectionWriter writer{operationContext(), &_coll.value()}; auto* indexCatalog = writer.getWritableCollection(operationContext())->getIndexCatalog(); uassertStatusOK(indexCatalog->createIndexOnEmptyCollection( @@ -170,13 +170,17 @@ protected: } const IndexCatalogEntry* getIndexEntry(const std::string& indexName) { - return _coll.get()->getIndexCatalog()->findIndexByName(operationContext(), indexName); + return _coll->getCollectionPtr()->getIndexCatalog()->findIndexByName(operationContext(), + indexName); } void setUp() override { CatalogTestFixture::setUp(); ASSERT_OK(storageInterface()->createCollection(operationContext(), _nss, {})); - _coll.emplace(operationContext(), _nss, MODE_X); + _coll = acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), _nss, AcquisitionPrerequisites::kWrite), + MODE_X); } void tearDown() override { @@ -189,7 +193,7 @@ protected: void testSingleOpIsSavedToSideWritesTable(IndexBuildInterceptor::Op op, LazyRecordStore::CreateMode createMode); - boost::optional _coll; + boost::optional _coll; private: NamespaceString _nss = NamespaceString::createNamespaceString_forTest("testDB.interceptor"); @@ -219,7 +223,7 @@ void IndexBuilderInterceptorTest::testSingleOpIsSavedToSideWritesTable( WriteUnitOfWork wuow(operationContext()); int64_t numKeys = 0; ASSERT_OK(interceptor->sideWrite( - operationContext(), *_coll.get(), entry, {keyString}, {}, {}, op, &numKeys)); + operationContext(), _coll->getCollectionPtr(), entry, {keyString}, {}, {}, op, &numKeys)); EXPECT_EQ(1, numKeys); wuow.commit(); @@ -278,7 +282,8 @@ TEST_F(IndexBuilderInterceptorTest, SingleInsertIsSavedToSkippedRecordsIntRidTra recordId.serializeToken("recordId", &builder); WriteUnitOfWork wuow(operationContext()); - interceptor->getSkippedRecordTracker().record(operationContext(), *_coll.get(), recordId); + interceptor->getSkippedRecordTracker().record( + operationContext(), _coll->getCollectionPtr(), recordId); wuow.commit(); auto skippedRecordsTable = getSkippedRecordsTableContents(indexBuildInfo); @@ -300,7 +305,8 @@ TEST_F(IndexBuilderInterceptorTest, SingleInsertIsSavedToSkippedRecordsTableIntR recordId.serializeToken("recordId", &builder); WriteUnitOfWork wuow(operationContext()); - interceptor->getSkippedRecordTracker().record(operationContext(), *_coll.get(), recordId); + interceptor->getSkippedRecordTracker().record( + operationContext(), _coll->getCollectionPtr(), recordId); wuow.commit(); auto skippedRecordsTable = getSkippedRecordsTableContents(indexBuildInfo); @@ -317,7 +323,8 @@ TEST_F(IndexBuilderInterceptorTest, SingleInsertIsSavedToskippedRecordsTableStri recordId.serializeToken("recordId", &builder); WriteUnitOfWork wuow(operationContext()); - interceptor->getSkippedRecordTracker().record(operationContext(), *_coll.get(), recordId); + interceptor->getSkippedRecordTracker().record( + operationContext(), _coll->getCollectionPtr(), recordId); wuow.commit(); auto skippedRecordsTable = getSkippedRecordsTableContents(indexBuildInfo); @@ -340,7 +347,8 @@ TEST_F(IndexBuilderInterceptorTest, recordId.serializeToken("recordId", &builder); WriteUnitOfWork wuow(operationContext()); - interceptor->getSkippedRecordTracker().record(operationContext(), *_coll.get(), recordId); + interceptor->getSkippedRecordTracker().record( + operationContext(), _coll->getCollectionPtr(), recordId); wuow.commit(); auto skippedRecordsTable = getSkippedRecordsTableContents(indexBuildInfo); @@ -359,7 +367,8 @@ TEST_F(IndexBuilderInterceptorTest, SingleInsertIsSavedToDuplicateKeyTable) { key_string::Value keyString(ksBuilder.release()); WriteUnitOfWork wuow(operationContext()); - ASSERT_OK(interceptor->recordDuplicateKey(operationContext(), *_coll.get(), entry, keyString)); + ASSERT_OK(interceptor->recordDuplicateKey( + operationContext(), _coll->getCollectionPtr(), entry, keyString)); wuow.commit(); key_string::View keyStringView(keyString); @@ -385,7 +394,8 @@ TEST_F(IndexBuilderInterceptorTest, SingleInsertIsSavedToDuplicateKeyTablePrimar key_string::Value keyString(ksBuilder.release()); WriteUnitOfWork wuow(operationContext()); - ASSERT_OK(interceptor->recordDuplicateKey(operationContext(), *_coll.get(), entry, keyString)); + ASSERT_OK(interceptor->recordDuplicateKey( + operationContext(), _coll->getCollectionPtr(), entry, keyString)); wuow.commit(); key_string::View keyStringView(keyString); @@ -429,7 +439,7 @@ TEST_F(IndexBuilderInterceptorTest, SingleInsertIsDrainedIntoIndexPrimaryDriven) WriteUnitOfWork wuow(operationContext()); int64_t numKeys = 0; ASSERT_OK(interceptor->sideWrite(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, {keyString}, {}, @@ -441,7 +451,7 @@ TEST_F(IndexBuilderInterceptorTest, SingleInsertIsDrainedIntoIndexPrimaryDriven) } ASSERT_OK(interceptor->drainWritesIntoIndex(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, InsertDeleteOptions{.dupsAllowed = true}, IndexBuildInterceptor::TrackDuplicates::kNoTrack, @@ -511,7 +521,7 @@ TEST_F(IndexBuilderInterceptorTest, SingleDeleteIsDrainedIntoIndexPrimaryDriven) int64_t numInserted = 0; ASSERT_OK(indexAccessMethod->insertKeys(operationContext(), ru, - *_coll.get(), + _coll->getCollectionPtr(), entry, keySet, InsertDeleteOptions{.dupsAllowed = true}, @@ -526,7 +536,7 @@ TEST_F(IndexBuilderInterceptorTest, SingleDeleteIsDrainedIntoIndexPrimaryDriven) WriteUnitOfWork wuow(operationContext()); int64_t numKeys = 0; ASSERT_OK(interceptor->sideWrite(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, {keyString}, {}, @@ -538,7 +548,7 @@ TEST_F(IndexBuilderInterceptorTest, SingleDeleteIsDrainedIntoIndexPrimaryDriven) } ASSERT_OK(interceptor->drainWritesIntoIndex(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, InsertDeleteOptions{.dupsAllowed = true}, IndexBuildInterceptor::TrackDuplicates::kNoTrack, @@ -582,7 +592,7 @@ TEST_F(IndexBuilderInterceptorTest, DeferredTableCreation) { { WriteUnitOfWork wuow(operationContext()); interceptor->getSkippedRecordTracker().record( - operationContext(), *_coll.get(), RecordId(1)); + operationContext(), _coll->getCollectionPtr(), RecordId(1)); wuow.commit(); } @@ -597,7 +607,7 @@ TEST_F(IndexBuilderInterceptorTest, DeferredTableCreation) { WriteUnitOfWork wuow(operationContext()); ASSERT_OK(interceptor->recordDuplicateKey( - operationContext(), *_coll.get(), entry, ksBuilder.release())); + operationContext(), _coll->getCollectionPtr(), entry, ksBuilder.release())); wuow.commit(); } @@ -651,16 +661,17 @@ TEST_F(IndexBuilderInterceptorTest, OpenExistingPreservesExistingData) { WriteUnitOfWork wuow(operationContext()); int64_t numKeys = 0; ASSERT_OK(interceptor->sideWrite(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, {keyString}, {}, {}, IndexBuildInterceptor::Op::kInsert, &numKeys)); - interceptor->getSkippedRecordTracker().record(operationContext(), *_coll.get(), recordId); - ASSERT_OK( - interceptor->recordDuplicateKey(operationContext(), *_coll.get(), entry, keyString)); + interceptor->getSkippedRecordTracker().record( + operationContext(), _coll->getCollectionPtr(), recordId); + ASSERT_OK(interceptor->recordDuplicateKey( + operationContext(), _coll->getCollectionPtr(), entry, keyString)); wuow.commit(); } @@ -794,7 +805,7 @@ TEST_F(IndexBuilderInterceptorTest, DrainSideWriteGeneratesNoContainerOpsWithout WriteUnitOfWork wuow(operationContext()); int64_t numKeys = 0; ASSERT_OK(interceptor->sideWrite(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, {keyString}, {}, @@ -810,7 +821,7 @@ TEST_F(IndexBuilderInterceptorTest, DrainSideWriteGeneratesNoContainerOpsWithout // Drain without PDIB — should use regular record store ops, not container writes. ASSERT_OK(interceptor->drainWritesIntoIndex(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, InsertDeleteOptions{.dupsAllowed = true}, IndexBuildInterceptor::TrackDuplicates::kNoTrack, @@ -848,7 +859,7 @@ TEST_F(IndexBuilderInterceptorTest, DrainInsertSideWriteGeneratesContainerOpsPri WriteUnitOfWork wuow(operationContext()); int64_t numKeys = 0; ASSERT_OK(interceptor->sideWrite(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, {keyString}, {}, @@ -864,7 +875,7 @@ TEST_F(IndexBuilderInterceptorTest, DrainInsertSideWriteGeneratesContainerOpsPri // Drain the side writes into the index. ASSERT_OK(interceptor->drainWritesIntoIndex(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, InsertDeleteOptions{.dupsAllowed = true}, IndexBuildInterceptor::TrackDuplicates::kNoTrack, @@ -904,7 +915,7 @@ TEST_F(IndexBuilderInterceptorTest, DrainDeleteSideWriteGeneratesContainerOpsPri int64_t numInserted = 0; ASSERT_OK(indexAccessMethod->insertKeys(operationContext(), ru, - *_coll.get(), + _coll->getCollectionPtr(), entry, keySet, InsertDeleteOptions{.dupsAllowed = true}, @@ -919,7 +930,7 @@ TEST_F(IndexBuilderInterceptorTest, DrainDeleteSideWriteGeneratesContainerOpsPri WriteUnitOfWork wuow(operationContext()); int64_t numKeys = 0; ASSERT_OK(interceptor->sideWrite(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, {keyString}, {}, @@ -935,7 +946,7 @@ TEST_F(IndexBuilderInterceptorTest, DrainDeleteSideWriteGeneratesContainerOpsPri // Drain the side writes into the index. ASSERT_OK(interceptor->drainWritesIntoIndex(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, InsertDeleteOptions{.dupsAllowed = true}, IndexBuildInterceptor::TrackDuplicates::kNoTrack, @@ -970,7 +981,7 @@ TEST_F(IndexBuilderInterceptorTest, DrainEmptySideWritesTableGeneratesNoContaine // Drain with no side writes buffered. ASSERT_OK(interceptor->drainWritesIntoIndex(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, InsertDeleteOptions{.dupsAllowed = true}, IndexBuildInterceptor::TrackDuplicates::kNoTrack, @@ -1000,7 +1011,7 @@ TEST_F(IndexBuilderInterceptorTest, DrainMultipleSideWritesGeneratesContainerOps WriteUnitOfWork wuow(operationContext()); int64_t numKeys = 0; ASSERT_OK(interceptor->sideWrite(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, {keyString}, {}, @@ -1016,7 +1027,7 @@ TEST_F(IndexBuilderInterceptorTest, DrainMultipleSideWritesGeneratesContainerOps // Drain all side writes. ASSERT_OK(interceptor->drainWritesIntoIndex(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, InsertDeleteOptions{.dupsAllowed = true}, IndexBuildInterceptor::TrackDuplicates::kNoTrack, @@ -1065,7 +1076,7 @@ TEST_F(IndexBuilderInterceptorTest, int64_t numInserted = 0; ASSERT_OK(indexAccessMethod->insertKeys(operationContext(), ru, - *_coll.get(), + _coll->getCollectionPtr(), entry, keySet, InsertDeleteOptions{.dupsAllowed = true}, @@ -1080,7 +1091,7 @@ TEST_F(IndexBuilderInterceptorTest, WriteUnitOfWork wuow(operationContext()); int64_t numKeys = 0; ASSERT_OK(interceptor->sideWrite(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, {insertKeyString}, {}, @@ -1096,7 +1107,7 @@ TEST_F(IndexBuilderInterceptorTest, WriteUnitOfWork wuow(operationContext()); int64_t numKeys = 0; ASSERT_OK(interceptor->sideWrite(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, {deleteKeyString}, {}, @@ -1112,7 +1123,7 @@ TEST_F(IndexBuilderInterceptorTest, // Drain all side writes. ASSERT_OK(interceptor->drainWritesIntoIndex(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, InsertDeleteOptions{.dupsAllowed = true}, IndexBuildInterceptor::TrackDuplicates::kNoTrack, @@ -1155,7 +1166,7 @@ TEST_F(IndexBuilderInterceptorTest, DrainMultipleBatchesGeneratesCorrectContaine WriteUnitOfWork wuow(operationContext()); int64_t numKeys = 0; ASSERT_OK(interceptor->sideWrite(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, {keyStrings.back()}, {}, @@ -1171,7 +1182,7 @@ TEST_F(IndexBuilderInterceptorTest, DrainMultipleBatchesGeneratesCorrectContaine // Drain all side writes — with batch size 1 this should produce multiple WUOWs. ASSERT_OK(interceptor->drainWritesIntoIndex(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, InsertDeleteOptions{.dupsAllowed = true}, IndexBuildInterceptor::TrackDuplicates::kNoTrack, @@ -1220,7 +1231,7 @@ TEST_F(IndexBuilderInterceptorTest, int64_t numInserted = 0; ASSERT_OK(indexAccessMethod->insertKeys(operationContext(), ru, - *_coll.get(), + _coll->getCollectionPtr(), entry, keySet, InsertDeleteOptions{.dupsAllowed = true}, @@ -1235,7 +1246,7 @@ TEST_F(IndexBuilderInterceptorTest, WriteUnitOfWork wuow(operationContext()); int64_t numKeys = 0; ASSERT_OK(interceptor->sideWrite(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, {dupKeyString}, {}, @@ -1253,7 +1264,7 @@ TEST_F(IndexBuilderInterceptorTest, // Drain with TrackDuplicates::kTrack — duplicates should be recorded to the constraint // violations table rather than causing a failure. ASSERT_OK(interceptor->drainWritesIntoIndex(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, InsertDeleteOptions{.dupsAllowed = true}, IndexBuildInterceptor::TrackDuplicates::kTrack, @@ -1299,7 +1310,7 @@ TEST_F(IndexBuilderInterceptorTest, WriteUnitOfWork wuow(operationContext()); int64_t numKeys = 0; ASSERT_OK(interceptor->sideWrite(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, {keyString}, {}, @@ -1316,7 +1327,7 @@ TEST_F(IndexBuilderInterceptorTest, // Drain with kTrack on a unique index — but since there's no duplicate, the constraint // violations table should not be written to. ASSERT_OK(interceptor->drainWritesIntoIndex(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, InsertDeleteOptions{.dupsAllowed = true}, IndexBuildInterceptor::TrackDuplicates::kTrack, @@ -1358,7 +1369,7 @@ TEST_F(IndexBuilderInterceptorTest, DrainDeleteOnUniqueIndexGeneratesContainerOp int64_t numInserted = 0; ASSERT_OK(indexAccessMethod->insertKeys(operationContext(), ru, - *_coll.get(), + _coll->getCollectionPtr(), entry, keySet, InsertDeleteOptions{.dupsAllowed = true}, @@ -1373,7 +1384,7 @@ TEST_F(IndexBuilderInterceptorTest, DrainDeleteOnUniqueIndexGeneratesContainerOp WriteUnitOfWork wuow(operationContext()); int64_t numKeys = 0; ASSERT_OK(interceptor->sideWrite(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, {keyString}, {}, @@ -1388,7 +1399,7 @@ TEST_F(IndexBuilderInterceptorTest, DrainDeleteOnUniqueIndexGeneratesContainerOp // Drain with kTrack on a unique index — delete path is unaffected by uniqueness. ASSERT_OK(interceptor->drainWritesIntoIndex(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, InsertDeleteOptions{.dupsAllowed = true}, IndexBuildInterceptor::TrackDuplicates::kTrack, @@ -1428,7 +1439,7 @@ TEST_F(IndexBuilderInterceptorTest, int64_t numInserted = 0; ASSERT_OK(indexAccessMethod->insertKeys(operationContext(), ru, - *_coll.get(), + _coll->getCollectionPtr(), entry, keySet, InsertDeleteOptions{.dupsAllowed = true}, @@ -1443,7 +1454,7 @@ TEST_F(IndexBuilderInterceptorTest, WriteUnitOfWork wuow(operationContext()); int64_t numKeys = 0; ASSERT_OK(interceptor->sideWrite(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, {dupKeyString}, {}, @@ -1460,7 +1471,7 @@ TEST_F(IndexBuilderInterceptorTest, // Drain with kNoTrack — duplicate is silently swallowed, not recorded to constraint // violations table. ASSERT_OK(interceptor->drainWritesIntoIndex(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, InsertDeleteOptions{.dupsAllowed = true}, IndexBuildInterceptor::TrackDuplicates::kNoTrack, @@ -1505,7 +1516,7 @@ TEST_F(IndexBuilderInterceptorTest, int64_t numInserted = 0; ASSERT_OK(indexAccessMethod->insertKeys(operationContext(), ru, - *_coll.get(), + _coll->getCollectionPtr(), entry, keySet, InsertDeleteOptions{.dupsAllowed = true}, @@ -1520,7 +1531,7 @@ TEST_F(IndexBuilderInterceptorTest, WriteUnitOfWork wuow(operationContext()); int64_t numKeys = 0; ASSERT_OK(interceptor->sideWrite(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, {dupKeyString}, {}, @@ -1539,7 +1550,7 @@ TEST_F(IndexBuilderInterceptorTest, // forces the error path even when options.dupsAllowed is true. auto status = interceptor->drainWritesIntoIndex(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, InsertDeleteOptions{.dupsAllowed = true}, IndexBuildInterceptor::TrackDuplicates::kTrack, @@ -1580,7 +1591,7 @@ TEST_F(IndexBuilderInterceptorTest, int64_t numInserted = 0; ASSERT_OK(indexAccessMethod->insertKeys(operationContext(), ru, - *_coll.get(), + _coll->getCollectionPtr(), entry, keySet, InsertDeleteOptions{.dupsAllowed = true}, @@ -1595,7 +1606,7 @@ TEST_F(IndexBuilderInterceptorTest, WriteUnitOfWork wuow(operationContext()); int64_t numKeys = 0; ASSERT_OK(interceptor->sideWrite(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, {keyString}, {}, @@ -1614,7 +1625,7 @@ TEST_F(IndexBuilderInterceptorTest, // is NOT invoked, so no constraint violation is recorded. This is an idempotent re-insert, // not a true duplicate. ASSERT_OK(interceptor->drainWritesIntoIndex(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, InsertDeleteOptions{.dupsAllowed = true}, IndexBuildInterceptor::TrackDuplicates::kTrack, @@ -1660,7 +1671,7 @@ TEST_F(IndexBuilderInterceptorTest, int64_t numInserted = 0; ASSERT_OK(indexAccessMethod->insertKeys(operationContext(), ru, - *_coll.get(), + _coll->getCollectionPtr(), entry, keySet, InsertDeleteOptions{.dupsAllowed = true}, @@ -1675,7 +1686,7 @@ TEST_F(IndexBuilderInterceptorTest, WriteUnitOfWork wuow(operationContext()); int64_t numKeys = 0; ASSERT_OK(interceptor->sideWrite(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, {dupKeyString}, {}, @@ -1693,7 +1704,7 @@ TEST_F(IndexBuilderInterceptorTest, // path regardless of the TrackDuplicates mode. auto status = interceptor->drainWritesIntoIndex(operationContext(), - *_coll.get(), + _coll->getCollectionPtr(), entry, InsertDeleteOptions{.dupsAllowed = true}, IndexBuildInterceptor::TrackDuplicates::kNoTrack, diff --git a/src/mongo/db/index_builds/index_build_test_helpers.cpp b/src/mongo/db/index_builds/index_build_test_helpers.cpp index dfcd2c26c9c..e911c2926d4 100644 --- a/src/mongo/db/index_builds/index_build_test_helpers.cpp +++ b/src/mongo/db/index_builds/index_build_test_helpers.cpp @@ -35,12 +35,14 @@ #include "mongo/db/index_builds/multi_index_block.h" #include "mongo/db/namespace_string.h" #include "mongo/db/service_context.h" +#include "mongo/db/shard_role/lock_manager/d_concurrency.h" #include "mongo/db/shard_role/lock_manager/lock_manager_defs.h" -#include "mongo/db/shard_role/shard_catalog/catalog_raii.h" #include "mongo/db/shard_role/shard_catalog/collection.h" +#include "mongo/db/shard_role/shard_catalog/database_holder.h" #include "mongo/db/shard_role/shard_catalog/index_catalog.h" #include "mongo/db/shard_role/shard_catalog/index_catalog_entry.h" #include "mongo/db/shard_role/shard_catalog/index_descriptor.h" +#include "mongo/db/shard_role/shard_role.h" #include "mongo/db/shard_role/transaction_resources.h" #include "mongo/db/topology/vector_clock/vector_clock_mutable.h" @@ -75,34 +77,39 @@ Status createIndexFromSpec(OperationContext* opCtx, }; { - AutoGetDb autoDb(opCtx, nss.dbName(), MODE_IX); - Lock::CollectionLock collLock(opCtx, nss, MODE_X); WriteUnitOfWork wunit(opCtx); - CollectionWriter writer{opCtx, nss}; - auto coll = writer.getWritableCollection(opCtx); - if (!coll) { - auto db = autoDb.ensureDbExists(opCtx); + auto acq = acquireCollection( + opCtx, + CollectionAcquisitionRequest::fromOpCtx(opCtx, nss, AcquisitionPrerequisites::kWrite), + MODE_X); + if (!acq.exists()) { + auto db = DatabaseHolder::get(opCtx)->openDb(opCtx, nss.dbName()); invariant(db); - coll = db->createCollection(opCtx, NamespaceString::createNamespaceString_forTest(ns)); + auto coll = + db->createCollection(opCtx, NamespaceString::createNamespaceString_forTest(ns)); + invariant(coll); } - invariant(coll); wunit.commit(); } MultiIndexBlock indexer; ScopeGuard abortOnExit([&] { - AutoGetDb autoDb(opCtx, nss.dbName(), MODE_IX); - Lock::CollectionLock collLock(opCtx, nss, MODE_X); - CollectionWriter collection(opCtx, nss); + auto acq = acquireCollection( + opCtx, + CollectionAcquisitionRequest::fromOpCtx(opCtx, nss, AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter collection(opCtx, &acq); indexer.abortIndexBuild(opCtx, collection, MultiIndexBlock::kNoopOnCleanUpFn); }); auto storageEngine = opCtx->getServiceContext()->getStorageEngine(); IndexBuildInfo indexBuildInfo(spec, *storageEngine, nss.dbName()); { - AutoGetDb autoDb(opCtx, nss.dbName(), MODE_IX); - Lock::CollectionLock collLock(opCtx, nss, MODE_X); - CollectionWriter collection(opCtx, nss); + auto acq = acquireCollection( + opCtx, + CollectionAcquisitionRequest::fromOpCtx(opCtx, nss, AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter collection(opCtx, &acq); Status status = indexer .init( opCtx, @@ -132,9 +139,11 @@ Status createIndexFromSpec(OperationContext* opCtx, return status; } - AutoGetDb autoDb(opCtx, nss.dbName(), MODE_IX); - Lock::CollectionLock collLock(opCtx, nss, MODE_X); - CollectionWriter collection(opCtx, nss); + auto acq = acquireCollection( + opCtx, + CollectionAcquisitionRequest::fromOpCtx(opCtx, nss, AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter collection(opCtx, &acq); if (auto status = indexer.retrySkippedRecords(opCtx, collection.get()); !status.isOK()) { return status; } diff --git a/src/mongo/db/index_builds/index_builds_manager_test.cpp b/src/mongo/db/index_builds/index_builds_manager_test.cpp index 93cdd46e534..baccb9ee9be 100644 --- a/src/mongo/db/index_builds/index_builds_manager_test.cpp +++ b/src/mongo/db/index_builds/index_builds_manager_test.cpp @@ -39,6 +39,7 @@ #include "mongo/db/shard_role/lock_manager/lock_manager_defs.h" #include "mongo/db/shard_role/shard_catalog/catalog_test_fixture.h" #include "mongo/db/shard_role/shard_catalog/collection_options.h" +#include "mongo/db/shard_role/shard_role.h" #include "mongo/db/storage/exceptions.h" #include "mongo/db/storage/ident.h" #include "mongo/idl/server_parameter_test_controller.h" @@ -86,8 +87,11 @@ void IndexBuildsManagerTest::createCollection(const NamespaceString& nss) { } UUID IndexBuildsManagerTest::getCollectionUUID() const { - AutoGetCollection autoColl(operationContext(), _nss, MODE_IS); - return autoColl->uuid(); + auto acq = acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), _nss, AcquisitionPrerequisites::kRead), + MODE_IS); + return acq.uuid(); } std::vector IndexBuildsManagerTest::makeSpecs(std::vector keys) { @@ -106,8 +110,11 @@ std::vector IndexBuildsManagerTest::makeSpecs(std::vectorinit(operationContext(), coll, @@ -350,8 +355,12 @@ TEST_F(MultiIndexBlockTest, PersistResumeStateOnAbortWithoutCleanup) { const auto buildUUID = UUID::gen(); indexer->setBuildUUID(buildUUID); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo1 = @@ -372,7 +381,7 @@ TEST_F(MultiIndexBlockTest, PersistResumeStateOnAbortWithoutCleanup) { indexer->setIsResumable(true); indexer->abortWithoutCleanup(operationContext(), coll.get()); auto indexBuildIdent = findPersistedResumeState( - operationContext(), buildUUID, IndexBuildPhaseEnum::kInitialized, autoColl->uuid()); + operationContext(), buildUUID, IndexBuildPhaseEnum::kInitialized, coll->uuid()); ASSERT_TRUE(indexBuildIdent); validateTempTableIdentsOnTeardown({*indexBuildInfo1.sideWritesIdent, *indexBuildIdent}); @@ -383,8 +392,12 @@ TEST_F(MultiIndexBlockTest, PersistResumeStateOnRequestAndCommit) { const auto buildUUID = UUID::gen(); indexer->setBuildUUID(buildUUID); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo1 = @@ -405,7 +418,7 @@ TEST_F(MultiIndexBlockTest, PersistResumeStateOnRequestAndCommit) { indexer->setIsResumable(true); indexer->persistResumeState(operationContext(), coll.get()); auto indexBuildIdent = findPersistedResumeState( - operationContext(), buildUUID, IndexBuildPhaseEnum::kInitialized, autoColl->uuid()); + operationContext(), buildUUID, IndexBuildPhaseEnum::kInitialized, coll->uuid()); ASSERT_TRUE(indexBuildIdent); { @@ -424,8 +437,12 @@ TEST_F(MultiIndexBlockTest, PersistResumeStateOnRequestAndCommit) { // persistResumeState survives a write conflict at the kInitialized phase. TEST_F(MultiIndexBlockResumableTest, PersistResumeStateSurvivesWriteConflict_Initialized) { auto indexer = getIndexer(); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto handle = initPrimaryDrivenResumableBuild(operationContext(), indexer, coll); auto* storageEngine = operationContext()->getServiceContext()->getStorageEngine(); @@ -446,7 +463,7 @@ TEST_F(MultiIndexBlockResumableTest, PersistResumeStateSurvivesWriteConflict_Ini ASSERT_TRUE(resumeInfo); EXPECT_EQ(handle.buildUUID, resumeInfo->getBuildUUID()); EXPECT_EQ(IndexBuildPhaseEnum::kInitialized, resumeInfo->getPhase()); - EXPECT_EQ(autoColl->uuid(), resumeInfo->getCollectionUUID()); + EXPECT_EQ(coll->uuid(), resumeInfo->getCollectionUUID()); // The retry must not produce a duplicate record: exactly one record must exist. EXPECT_EQ(1u, countRecordsInIdent(operationContext(), storageEngine, handle.indexBuildIdent)); @@ -457,11 +474,15 @@ TEST_F(MultiIndexBlockResumableTest, PersistResumeStateSurvivesWriteConflict_Ini // persistResumeState survives a write conflict at the kBulkLoad phase. TEST_F(MultiIndexBlockResumableTest, PersistResumeStateSurvivesWriteConflict_BulkLoad) { auto indexer = getIndexer(); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto handle = - setUpKReplicatePrimaryDrivenBuild(operationContext(), indexer, autoColl, coll, getNSS()); + setUpKReplicatePrimaryDrivenBuild(operationContext(), indexer, acq, coll, getNSS()); auto* storageEngine = operationContext()->getServiceContext()->getStorageEngine(); { @@ -479,7 +500,7 @@ TEST_F(MultiIndexBlockResumableTest, PersistResumeStateSurvivesWriteConflict_Bul storageEngine, operationContext(), handle.indexBuildIdent); ASSERT_TRUE(resumeInfo); EXPECT_EQ(IndexBuildPhaseEnum::kBulkLoad, resumeInfo->getPhase()); - EXPECT_EQ(autoColl->uuid(), resumeInfo->getCollectionUUID()); + EXPECT_EQ(coll->uuid(), resumeInfo->getCollectionUUID()); // The retry must not produce a duplicate record: exactly one record must exist. EXPECT_EQ(1u, countRecordsInIdent(operationContext(), storageEngine, handle.indexBuildIdent)); @@ -491,15 +512,19 @@ TEST_F(MultiIndexBlockResumableTest, PersistResumeStateSurvivesWriteConflict_Bul // kDrainWrites phase. TEST_F(MultiIndexBlockResumableTest, PersistResumeStateSurvivesWriteConflict_DrainWrites) { auto indexer = getIndexer(); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto handle = initPrimaryDrivenResumableBuild(operationContext(), indexer, coll); auto* storageEngine = operationContext()->getServiceContext()->getStorageEngine(); { WriteUnitOfWork wuow(operationContext()); - ASSERT_OK(Helpers::insert(operationContext(), *autoColl, BSON("_id" << 0 << "a" << 1))); + ASSERT_OK(Helpers::insert(operationContext(), coll.get(), BSON("_id" << 0 << "a" << 1))); wuow.commit(); } ASSERT_OK(indexer->insertAllDocumentsInCollection(operationContext(), getNSS())); @@ -523,7 +548,7 @@ TEST_F(MultiIndexBlockResumableTest, PersistResumeStateSurvivesWriteConflict_Dra ASSERT_TRUE(resumeInfo); EXPECT_EQ(handle.buildUUID, resumeInfo->getBuildUUID()); EXPECT_EQ(IndexBuildPhaseEnum::kDrainWrites, resumeInfo->getPhase()); - EXPECT_EQ(autoColl->uuid(), resumeInfo->getCollectionUUID()); + EXPECT_EQ(coll->uuid(), resumeInfo->getCollectionUUID()); // The retry must not produce a duplicate record: exactly one record must exist. EXPECT_EQ(1u, countRecordsInIdent(operationContext(), storageEngine, handle.indexBuildIdent)); @@ -534,8 +559,12 @@ TEST_F(MultiIndexBlockResumableTest, PersistResumeStateSurvivesWriteConflict_Dra // _writeStateToContainer fired from abortWithoutCleanup survives a write conflict. TEST_F(MultiIndexBlockResumableTest, PersistResumeStateSurvivesWriteConflict_AbortWithoutCleanup) { auto indexer = getIndexer(); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto handle = initPrimaryDrivenResumableBuild(operationContext(), indexer, coll); auto* storageEngine = operationContext()->getServiceContext()->getStorageEngine(); @@ -558,7 +587,7 @@ TEST_F(MultiIndexBlockResumableTest, PersistResumeStateSurvivesWriteConflict_Abo // abortWithoutCleanup does not advance _phase, so the persisted state carries the phase the // build was in when abort was called (kInitialized here, since the test stops after init()). EXPECT_EQ(IndexBuildPhaseEnum::kInitialized, resumeInfo->getPhase()); - EXPECT_EQ(autoColl->uuid(), resumeInfo->getCollectionUUID()); + EXPECT_EQ(coll->uuid(), resumeInfo->getCollectionUUID()); EXPECT_EQ(1u, countRecordsInIdent(operationContext(), storageEngine, handle.indexBuildIdent)); @@ -572,8 +601,12 @@ TEST_F(MultiIndexBlockTest, PersistResumeStateOnRequestAndOnAbort) { const auto buildUUID = UUID::gen(); indexer->setBuildUUID(buildUUID); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo1 = @@ -594,7 +627,7 @@ TEST_F(MultiIndexBlockTest, PersistResumeStateOnRequestAndOnAbort) { indexer->setIsResumable(true); indexer->persistResumeState(operationContext(), coll.get()); auto indexBuildIdent = findPersistedResumeState( - operationContext(), buildUUID, IndexBuildPhaseEnum::kInitialized, autoColl->uuid()); + operationContext(), buildUUID, IndexBuildPhaseEnum::kInitialized, coll->uuid()); EXPECT_TRUE(indexBuildIdent); indexer->abortWithoutCleanup(operationContext(), coll.get()); @@ -607,8 +640,12 @@ TEST_F(MultiIndexBlockTest, PersistResumeStateOnRequestAndOnAbort) { TEST_F(MultiIndexBlockTest, InitWriteConflictException) { auto indexer = getIndexer(); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo = @@ -652,8 +689,12 @@ TEST_F(MultiIndexBlockTest, InitWriteConflictException) { TEST_F(MultiIndexBlockTest, InitMultipleSpecs) { auto indexer = getIndexer(); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo1 = @@ -758,8 +799,11 @@ TEST_F(MultiIndexBlockTest, InitMultipleSpecs) { TEST_F(MultiIndexBlockTest, AddDocumentBetweenInitAndInsertAll) { auto indexer = getIndexer(); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); auto storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo = @@ -770,6 +814,7 @@ TEST_F(MultiIndexBlockTest, AddDocumentBetweenInitAndInsertAll) { *storageEngine); { + CollectionWriter coll(operationContext(), &acq); WriteUnitOfWork wuow(operationContext()); ASSERT_OK(indexer ->init(operationContext(), @@ -784,7 +829,8 @@ TEST_F(MultiIndexBlockTest, AddDocumentBetweenInitAndInsertAll) { { WriteUnitOfWork wuow(operationContext()); - ASSERT_OK(Helpers::insert(operationContext(), *autoColl, BSON("_id" << 0 << "a" << 1))); + ASSERT_OK(Helpers::insert( + operationContext(), acq.getCollectionPtr(), BSON("_id" << 0 << "a" << 1))); wuow.commit(); } @@ -794,6 +840,7 @@ TEST_F(MultiIndexBlockTest, AddDocumentBetweenInitAndInsertAll) { IndexBuildInterceptor::DrainYieldPolicy::kNoYield)); { + CollectionWriter coll(operationContext(), &acq); WriteUnitOfWork wuow(operationContext()); ASSERT_OK(indexer->commit(operationContext(), coll.getWritableCollection(operationContext()), @@ -821,10 +868,14 @@ TEST_F(MultiIndexBlockTest, DrainBackgroundWritesYieldIsTracked) { *storageEngine); { - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); { + CollectionWriter coll(operationContext(), &acq); WriteUnitOfWork wuow(operationContext()); ASSERT_OK(indexer ->init(operationContext(), @@ -839,7 +890,8 @@ TEST_F(MultiIndexBlockTest, DrainBackgroundWritesYieldIsTracked) { { WriteUnitOfWork wuow(operationContext()); - ASSERT_OK(Helpers::insert(operationContext(), *autoColl, BSON("_id" << 0 << "a" << 1))); + ASSERT_OK(Helpers::insert( + operationContext(), acq.getCollectionPtr(), BSON("_id" << 0 << "a" << 1))); wuow.commit(); } @@ -847,7 +899,11 @@ TEST_F(MultiIndexBlockTest, DrainBackgroundWritesYieldIsTracked) { } { - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_IX); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_IX); ASSERT_OK(indexer->drainBackgroundWrites(operationContext(), RecoveryUnit::ReadSource::kNoTimestamp, IndexBuildInterceptor::DrainYieldPolicy::kYield)); @@ -860,8 +916,12 @@ TEST_F(MultiIndexBlockTest, DrainBackgroundWritesYieldIsTracked) { } { - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); WriteUnitOfWork wuow(operationContext()); ASSERT_OK(indexer->commit(operationContext(), coll.getWritableCollection(operationContext()), @@ -876,8 +936,12 @@ TEST_F(MultiIndexBlockTest, CommitUsesCommitTimestampForTemporaryTableDrops) { const auto buildUUID = UUID::gen(); indexer->setBuildUUID(buildUUID); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo = @@ -934,8 +998,12 @@ TEST_F(MultiIndexBlockTest, CommitWithNoCommitTimestampDropsImmediately) { const auto buildUUID = UUID::gen(); indexer->setBuildUUID(buildUUID); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo = @@ -979,8 +1047,12 @@ TEST_F(MultiIndexBlockTest, CommitWithNoCommitTimestampDropsImmediately) { TEST_F(MultiIndexBlockTest, AbortDropsTemporaryTables) { auto indexer = getIndexer(); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo = @@ -1026,8 +1098,12 @@ TEST_F(MultiIndexBlockTest, CommitDropsResumablePrimaryDrivenIndexBuildTable) { indexer->setContainerWriteBehavior(ContainerWriteBehavior::kReplicate); indexer->setIsResumable(true); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo = @@ -1075,8 +1151,12 @@ TEST_F(MultiIndexBlockTest, InitSkipsResumablePrimaryDrivenIndexBuildTableWhenNo indexer->setContainerWriteBehavior(ContainerWriteBehavior::kReplicate); // Intentionally leave _isResumable at its default (false). - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo = @@ -1115,8 +1195,12 @@ TEST_F(MultiIndexBlockTest, AbortDropsResumablePrimaryDrivenIndexBuildTable) { indexer->setContainerWriteBehavior(ContainerWriteBehavior::kReplicate); indexer->setIsResumable(true); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo = @@ -1167,8 +1251,12 @@ TEST_F(MultiIndexBlockTest, PdibPersistsResumeStateOnFirstDrain) { indexer->setContainerWriteBehavior(ContainerWriteBehavior::kReplicate); indexer->setIsResumable(true); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo = @@ -1190,7 +1278,7 @@ TEST_F(MultiIndexBlockTest, PdibPersistsResumeStateOnFirstDrain) { // creates the bulk loader for the kReplicate path. { WriteUnitOfWork wuow(operationContext()); - ASSERT_OK(Helpers::insert(operationContext(), *autoColl, BSON("_id" << 0 << "a" << 1))); + ASSERT_OK(Helpers::insert(operationContext(), coll.get(), BSON("_id" << 0 << "a" << 1))); wuow.commit(); } @@ -1215,7 +1303,7 @@ TEST_F(MultiIndexBlockTest, PdibPersistsResumeStateOnFirstDrain) { storageEngine, operationContext(), ident::generateNewIndexBuildIdent(buildUUID)); ASSERT_TRUE(resumeInfo); EXPECT_EQ(IndexBuildPhaseEnum::kDrainWrites, resumeInfo->getPhase()); - EXPECT_EQ(autoColl->uuid(), resumeInfo->getCollectionUUID()); + EXPECT_EQ(coll->uuid(), resumeInfo->getCollectionUUID()); // Re-entering drain (second/third pass in production) must not error and must leave the // record intact. Subsequent calls hit firstDrain == false and skip the persist. @@ -1252,8 +1340,12 @@ TEST_F(MultiIndexBlockTest, ResumePdibDuringDrain) { indexer->setContainerWriteBehavior(ContainerWriteBehavior::kReplicate); indexer->setIsResumable(true); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo = @@ -1273,7 +1365,7 @@ TEST_F(MultiIndexBlockTest, ResumePdibDuringDrain) { { WriteUnitOfWork wuow(operationContext()); - ASSERT_OK(Helpers::insert(operationContext(), *autoColl, BSON("_id" << 0 << "a" << 1))); + ASSERT_OK(Helpers::insert(operationContext(), coll.get(), BSON("_id" << 0 << "a" << 1))); wuow.commit(); } @@ -1289,7 +1381,7 @@ TEST_F(MultiIndexBlockTest, ResumePdibDuringDrain) { // (openExisting) rather than recreating it (immediate). { WriteUnitOfWork wuow(operationContext()); - ASSERT_OK(Helpers::insert(operationContext(), *autoColl, BSON("_id" << 1 << "a" << 2))); + ASSERT_OK(Helpers::insert(operationContext(), coll.get(), BSON("_id" << 1 << "a" << 2))); wuow.commit(); } @@ -1388,8 +1480,12 @@ TEST_F(MultiIndexBlockTest, ResumedPdibPersistsStateOnFirstDrainWithNoNewRecords idx.setIsResumable(true); }; - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto& engine = *operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo = @@ -1406,7 +1502,7 @@ TEST_F(MultiIndexBlockTest, ResumedPdibPersistsStateOnFirstDrainWithNoNewRecords std::string val(64 * 1024, 'a'); for (auto i = 0; i < 20; ++i) { ASSERT_OK( - Helpers::insert(operationContext(), *autoColl, BSON("_id" << i << "a" << val))); + Helpers::insert(operationContext(), coll.get(), BSON("_id" << i << "a" << val))); } wuow.commit(); } @@ -1483,8 +1579,12 @@ TEST_F(MultiIndexBlockTest, PdibSkipsResumeStateOnEmptyCollection) { indexer->setContainerWriteBehavior(ContainerWriteBehavior::kReplicate); indexer->setIsResumable(true); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo = @@ -1537,8 +1637,12 @@ TEST_F(MultiIndexBlockTest, PdibDoesNotPersistResumeStateWhenFeatureFlagOff) { // mirror that here so init() takes the non-replicated path (no resume table created). indexer->setContainerWriteBehavior(ContainerWriteBehavior::kDoNotReplicate); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo = @@ -1573,8 +1677,12 @@ TEST_F(MultiIndexBlockTest, AbortWithoutCleanupDoesNotDropTables) { const auto buildUUID = UUID::gen(); indexer->setBuildUUID(buildUUID); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo = @@ -1622,8 +1730,12 @@ TEST_F(MultiIndexBlockTest, BasicMetrics) { capturer.readInt64Counter(otel::metrics::MetricNames::kIndexBuildKeysInsertedFromScan); } - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto spec1 = @@ -1655,8 +1767,8 @@ TEST_F(MultiIndexBlockTest, BasicMetrics) { { WriteUnitOfWork wuow(operationContext()); - ASSERT_OK(Helpers::insert(operationContext(), *autoColl, BSON("_id" << 0 << "a" << 1))); - ASSERT_OK(Helpers::insert(operationContext(), *autoColl, BSON("_id" << 1 << "a" << 2))); + ASSERT_OK(Helpers::insert(operationContext(), coll.get(), BSON("_id" << 0 << "a" << 1))); + ASSERT_OK(Helpers::insert(operationContext(), coll.get(), BSON("_id" << 1 << "a" << 2))); wuow.commit(); } constexpr size_t numDocsInColl = 2; @@ -1701,8 +1813,12 @@ TEST_F(MultiIndexBlockTest, BasicMetrics) { TEST_F(MultiIndexBlockTest, AbortWithNoCommitTimestampDropsImmediately) { auto indexer = getIndexer(); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo = @@ -1811,11 +1927,11 @@ void promoteMockReplCoordToPrimary(ServiceContext* service) { // Setup for a primary-driven (kReplicate) build: assigns a build UUID, flips the container-write // behavior, inserts one document into the collection (so the scan doesn't short-circuit on // emptiness), constructs a single-spec IndexBuildInfo, runs init and the collection scan so -// index.bulk is populated for _constructStateObject. Caller still owns the AutoGetCollection / +// index.bulk is populated for _constructStateObject. Caller still owns the CollectionAcquisition / // CollectionWriter and the feature-flag scope. KReplicateBuildHandle setUpKReplicatePrimaryDrivenBuild(OperationContext* opCtx, MultiIndexBlock* indexer, - AutoGetCollection& autoColl, + CollectionAcquisition& acq, CollectionWriter& coll, const NamespaceString& nss) { const auto buildUUID = UUID::gen(); @@ -1826,7 +1942,7 @@ KReplicateBuildHandle setUpKReplicatePrimaryDrivenBuild(OperationContext* opCtx, { WriteUnitOfWork wuow(opCtx); - ASSERT_OK(Helpers::insert(opCtx, *autoColl, BSON("_id" << 0 << "a" << 1))); + ASSERT_OK(Helpers::insert(opCtx, coll.get(), BSON("_id" << 0 << "a" << 1))); wuow.commit(); } @@ -1895,12 +2011,16 @@ TEST_F(MultiIndexBlockTest, CommitToleratesKeysAlreadyInContainer) { indexer->setContainerWriteBehavior(ContainerWriteBehavior::kReplicate); indexer->setIsResumable(true); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); { WriteUnitOfWork wuow{operationContext()}; - ASSERT_OK(Helpers::insert(operationContext(), *autoColl, BSON("_id" << 0 << "a" << 1))); + ASSERT_OK(Helpers::insert(operationContext(), coll.get(), BSON("_id" << 0 << "a" << 1))); wuow.commit(); } @@ -1920,13 +2040,13 @@ TEST_F(MultiIndexBlockTest, CommitToleratesKeysAlreadyInContainer) { boost::none)); ASSERT_OK(indexer->insertAllDocumentsInCollection(operationContext(), getNSS())); - auto* indexEntry = autoColl->getIndexCatalog()->findIndexByName( + auto* indexEntry = coll.get()->getIndexCatalog()->findIndexByName( operationContext(), "a_1", IndexCatalog::InclusionPolicy::kUnfinished); ASSERT(indexEntry); auto* iam = indexEntry->accessMethod()->asSortedData(); ASSERT(iam); - auto record = autoColl->getCursor(operationContext())->next(); + auto record = coll.get()->getCursor(operationContext())->next(); ASSERT(record); auto recordId = record->id; @@ -1936,7 +2056,7 @@ TEST_F(MultiIndexBlockTest, CommitToleratesKeysAlreadyInContainer) { KeyStringSet multikeyMetadataKeys; auto multikeyPaths = containerPool.multikeyPaths(); iam->getKeys(operationContext(), - *autoColl, + coll.get(), indexEntry, pooledBuilder, BSON("_id" << 0 << "a" << 1), @@ -1989,11 +2109,15 @@ TEST_F(MultiIndexBlockTest, PersistResumeStateUsesContainerWrites) { auto& observer = installResumeStateContainerObserver(operationContext()); auto indexer = getIndexer(); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto handle = - setUpKReplicatePrimaryDrivenBuild(operationContext(), indexer, autoColl, coll, getNSS()); + setUpKReplicatePrimaryDrivenBuild(operationContext(), indexer, acq, coll, getNSS()); auto* storageEngine = operationContext()->getServiceContext()->getStorageEngine(); EXPECT_TRUE(storageEngine->getEngine()->hasIdent( @@ -2014,7 +2138,7 @@ TEST_F(MultiIndexBlockTest, PersistResumeStateUsesContainerWrites) { storageEngine, operationContext(), handle.indexBuildIdent); ASSERT_TRUE(resumeInfo); EXPECT_EQ(handle.buildUUID, resumeInfo->getBuildUUID()); - EXPECT_EQ(autoColl->uuid(), resumeInfo->getCollectionUUID()); + EXPECT_EQ(coll->uuid(), resumeInfo->getCollectionUUID()); // Per-index IndexStateInfo round-trips with the input spec / idents. ASSERT_EQ(1U, resumeInfo->getIndexes().size()); @@ -2049,11 +2173,15 @@ TEST_F(MultiIndexBlockTest, PersistResumeStateOverwritesPriorState) { auto& observer = installResumeStateContainerObserver(operationContext()); auto indexer = getIndexer(); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto handle = - setUpKReplicatePrimaryDrivenBuild(operationContext(), indexer, autoColl, coll, getNSS()); + setUpKReplicatePrimaryDrivenBuild(operationContext(), indexer, acq, coll, getNSS()); // The load phase already produced one write; each persistResumeState() must add exactly one // more, and the second must be an update (key already exists after the first). @@ -2093,11 +2221,15 @@ TEST_F(MultiIndexBlockTest, AbortWithoutCleanupUsesContainerWrites) { auto& observer = installResumeStateContainerObserver(operationContext()); auto indexer = getIndexer(); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto handle = - setUpKReplicatePrimaryDrivenBuild(operationContext(), indexer, autoColl, coll, getNSS()); + setUpKReplicatePrimaryDrivenBuild(operationContext(), indexer, acq, coll, getNSS()); // The load phase already produced one write; abortWithoutCleanup must add exactly one more. const auto writesBefore = observer.countInsertsForIdent(handle.indexBuildIdent) + @@ -2113,7 +2245,7 @@ TEST_F(MultiIndexBlockTest, AbortWithoutCleanupUsesContainerWrites) { storageEngine, operationContext(), handle.indexBuildIdent); ASSERT_TRUE(resumeInfo); EXPECT_EQ(handle.buildUUID, resumeInfo->getBuildUUID()); - EXPECT_EQ(autoColl->uuid(), resumeInfo->getCollectionUUID()); + EXPECT_EQ(coll->uuid(), resumeInfo->getCollectionUUID()); EXPECT_EQ(1U, resumeInfo->getIndexes().size()); // After abortWithoutCleanup the per-build table must still exist (resumable shutdown). @@ -2133,11 +2265,15 @@ TEST_F(MultiIndexBlockTest, PersistResumeStateNoOpWhenNotResumable) { auto& observer = installResumeStateContainerObserver(operationContext()); auto indexer = getIndexer(); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto handle = - setUpKReplicatePrimaryDrivenBuild(operationContext(), indexer, autoColl, coll, getNSS()); + setUpKReplicatePrimaryDrivenBuild(operationContext(), indexer, acq, coll, getNSS()); indexer->setIsResumable(false); // The load phase already produced one write; with isResumable=false, persistResumeState @@ -2176,8 +2312,12 @@ TEST_F(MultiIndexBlockTest, HybridBuildDoesNotUseContainerWrites) { indexer->setIsResumable(true); // No setContainerWriteBehavior — defaults to kDoNotReplicate (hybrid). - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto* storageEngine = operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo = @@ -2216,8 +2356,12 @@ TEST_F(MultiIndexBlockTest, WriteStateToContainerOnSpillWhenResumable) { auto& observer = installResumeStateContainerObserver(operationContext()); auto& indexer = *getIndexer(); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto buildUUID = UUID::gen(); indexer.setBuildUUID(buildUUID); @@ -2230,7 +2374,7 @@ TEST_F(MultiIndexBlockTest, WriteStateToContainerOnSpillWhenResumable) { WriteUnitOfWork wuow(operationContext()); std::string val(64 * 1024, 'a'); for (auto i = 0; i < 20; ++i) { - ASSERT_OK(Helpers::insert(operationContext(), *autoColl, BSON("_id" << i << "a" << val))); + ASSERT_OK(Helpers::insert(operationContext(), coll.get(), BSON("_id" << i << "a" << val))); } wuow.commit(); @@ -2264,7 +2408,7 @@ TEST_F(MultiIndexBlockTest, WriteStateToContainerOnSpillWhenResumable) { index_builds::readAndParseResumeIndexInfo(&engine, operationContext(), indexBuildIdent); ASSERT_TRUE(resumeInfo.has_value()); EXPECT_EQ(resumeInfo->getBuildUUID(), buildUUID); - EXPECT_EQ(resumeInfo->getCollectionUUID(), autoColl->uuid()); + EXPECT_EQ(resumeInfo->getCollectionUUID(), coll->uuid()); ASSERT_EQ(resumeInfo->getIndexes().size(), 1); EXPECT_EQ(resumeInfo->getIndexes()[0].getSpec()["name"].String(), "a_1"); @@ -2283,8 +2427,12 @@ TEST_F(MultiIndexBlockTest, OnSpillCallbackSeesLatestRecordIdAndKeyCount) { promoteMockReplCoordToPrimary(getServiceContext()); auto& indexer = *getIndexer(); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto buildUUID = UUID::gen(); indexer.setBuildUUID(buildUUID); @@ -2294,7 +2442,7 @@ TEST_F(MultiIndexBlockTest, OnSpillCallbackSeesLatestRecordIdAndKeyCount) { { WriteUnitOfWork wuow{operationContext()}; - ASSERT_OK(Helpers::insert(operationContext(), *autoColl, BSON("_id" << 0 << "a" << 1))); + ASSERT_OK(Helpers::insert(operationContext(), coll.get(), BSON("_id" << 0 << "a" << 1))); wuow.commit(); } @@ -2343,8 +2491,12 @@ TEST_F(MultiIndexBlockTest, OnSpillRecordsLastSpilledRecordId) { promoteMockReplCoordToPrimary(getServiceContext()); auto& indexer = *getIndexer(); - AutoGetCollection autoColl{operationContext(), getNSS(), MODE_X}; - CollectionWriter coll{operationContext(), autoColl}; + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll{operationContext(), &acq}; auto buildUUID = UUID::gen(); indexer.setBuildUUID(buildUUID); @@ -2356,7 +2508,7 @@ TEST_F(MultiIndexBlockTest, OnSpillRecordsLastSpilledRecordId) { std::string val(64 * 1024, 'a'); auto numDocs = 20; for (auto i = 0; i < numDocs; ++i) { - ASSERT_OK(Helpers::insert(operationContext(), *autoColl, BSON("_id" << i << "a" << val))); + ASSERT_OK(Helpers::insert(operationContext(), coll.get(), BSON("_id" << i << "a" << val))); } wuow.commit(); @@ -2408,8 +2560,12 @@ TEST_F(MultiIndexBlockTest, OnSpillRecordsLastSpilledRecordIdForMultipleIndexes) promoteMockReplCoordToPrimary(getServiceContext()); auto& indexer = *getIndexer(); - AutoGetCollection autoColl{operationContext(), getNSS(), MODE_X}; - CollectionWriter coll{operationContext(), autoColl}; + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll{operationContext(), &acq}; auto buildUUID = UUID::gen(); indexer.setBuildUUID(buildUUID); @@ -2422,7 +2578,7 @@ TEST_F(MultiIndexBlockTest, OnSpillRecordsLastSpilledRecordIdForMultipleIndexes) auto numDocs = 20; for (auto i = 0; i < numDocs; ++i) { ASSERT_OK(Helpers::insert(operationContext(), - *autoColl, + coll.get(), BSON("_id" << i << "a" << val << "b" << val << "c" << val))); } wuow.commit(); @@ -2491,8 +2647,12 @@ TEST_F(MultiIndexBlockTest, ResumePdibDuringCollectionScan) { idx.setIsResumable(true); }; - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto& engine = *operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo = @@ -2517,7 +2677,7 @@ TEST_F(MultiIndexBlockTest, ResumePdibDuringCollectionScan) { std::string val(64 * 1024, 'a'); for (auto i = 0; i < 20; ++i) { ASSERT_OK( - Helpers::insert(operationContext(), *autoColl, BSON("_id" << i << "a" << val))); + Helpers::insert(operationContext(), coll.get(), BSON("_id" << i << "a" << val))); } wuow.commit(); } @@ -2531,7 +2691,7 @@ TEST_F(MultiIndexBlockTest, ResumePdibDuringCollectionScan) { ASSERT_TRUE(resumeInfo); EXPECT_EQ(buildUUID, resumeInfo->getBuildUUID()); EXPECT_EQ(IndexBuildPhaseEnum::kCollectionScan, resumeInfo->getPhase()); - EXPECT_EQ(autoColl->uuid(), resumeInfo->getCollectionUUID()); + EXPECT_EQ(coll->uuid(), resumeInfo->getCollectionUUID()); // The persisted scan position is a valid RecordId inside the 20-doc collection. // A valid spill checkpoint must satisfy 0 < position <= 20. @@ -2618,8 +2778,12 @@ TEST_F(MultiIndexBlockTest, PdibResumedScanSkipsRecordsAtOrBeforePerIndexLastSpi boost::optional resumeInfo; { - AutoGetCollection autoColl{operationContext(), getNSS(), MODE_X}; - CollectionWriter coll{operationContext(), autoColl}; + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll{operationContext(), &acq}; { WriteUnitOfWork wuow{operationContext()}; @@ -2627,7 +2791,7 @@ TEST_F(MultiIndexBlockTest, PdibResumedScanSkipsRecordsAtOrBeforePerIndexLastSpi for (auto i = 0; i < initialDocs; ++i) { ASSERT_OK( Helpers::insert(operationContext(), - *autoColl, + coll.get(), BSON("_id" << i << "a" << val << "b" << val << "c" << val))); } wuow.commit(); @@ -2661,12 +2825,16 @@ TEST_F(MultiIndexBlockTest, PdibResumedScanSkipsRecordsAtOrBeforePerIndexLastSpi // originalLastSpilled. These docs exist on disk but aren't represented in any sorter's spilled // state. { - AutoGetCollection autoColl{operationContext(), getNSS(), MODE_X}; + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); WriteUnitOfWork wuow{operationContext()}; std::string val(64 * 1024, 'a'); for (auto i = initialDocs; i < totalDocs; ++i) { ASSERT_OK(Helpers::insert(operationContext(), - *autoColl, + acq.getCollectionPtr(), BSON("_id" << i << "a" << val << "b" << val << "c" << val))); } wuow.commit(); @@ -2766,8 +2934,12 @@ TEST_F(MultiIndexBlockTest, ResumeRestoresLastSpilledRecordId) { idx.setIsResumable(true); }; - AutoGetCollection autoColl{operationContext(), getNSS(), MODE_X}; - CollectionWriter coll{operationContext(), autoColl}; + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll{operationContext(), &acq}; auto& engine = *operationContext()->getServiceContext()->getStorageEngine(); auto indexBuildInfo = @@ -2791,7 +2963,7 @@ TEST_F(MultiIndexBlockTest, ResumeRestoresLastSpilledRecordId) { std::string val(64 * 1024, 'a'); for (auto i = 0; i < 20; ++i) { ASSERT_OK( - Helpers::insert(operationContext(), *autoColl, BSON("_id" << i << "a" << val))); + Helpers::insert(operationContext(), coll.get(), BSON("_id" << i << "a" << val))); } wuow.commit(); } @@ -2867,9 +3039,13 @@ TEST_F(MultiIndexBlockTest, ResumePdibDuringLoad) { UUID collectionUUID = UUID::gen(); auto numDocs = 20; { - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); - collectionUUID = autoColl->uuid(); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); + collectionUUID = acq.uuid(); auto& indexer = *getIndexer(); configurePdib(indexer); @@ -2884,8 +3060,8 @@ TEST_F(MultiIndexBlockTest, ResumePdibDuringLoad) { WriteUnitOfWork wuow(operationContext()); std::string val(64 * 1024, 'a'); for (auto i = 0; i < numDocs; ++i) { - ASSERT_OK( - Helpers::insert(operationContext(), *autoColl, BSON("_id" << i << "a" << val))); + ASSERT_OK(Helpers::insert( + operationContext(), coll.get(), BSON("_id" << i << "a" << val))); } wuow.commit(); } @@ -2985,8 +3161,12 @@ TEST_F(MultiIndexBlockTest, ResumedPdibSpillerContinuesContainerKeysPastPriorRan idx.setIsResumable(true); }; - AutoGetCollection autoColl{operationContext(), getNSS(), MODE_X}; - CollectionWriter coll{operationContext(), autoColl}; + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll{operationContext(), &acq}; auto& engine = *operationContext()->getServiceContext()->getStorageEngine(); IndexBuildInfo indexBuildInfo{BSON("key" << BSON("a" << 1) << "name" @@ -3001,7 +3181,7 @@ TEST_F(MultiIndexBlockTest, ResumedPdibSpillerContinuesContainerKeysPastPriorRan std::string val(64 * 1024, 'a'); for (int i = 0; i < count; ++i) { ASSERT_OK(Helpers::insert( - operationContext(), *autoColl, BSON("_id" << (firstId + i) << "a" << val))); + operationContext(), coll.get(), BSON("_id" << (firstId + i) << "a" << val))); } wuow.commit(); }; @@ -3085,8 +3265,12 @@ TEST_F(MultiIndexBlockTest, DoNotWriteStateToContainerOnSpillWhenNotResumable) { auto& observer = installResumeStateContainerObserver(operationContext()); auto& indexer = *getIndexer(); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto buildUUID = UUID::gen(); indexer.setBuildUUID(buildUUID); @@ -3099,7 +3283,7 @@ TEST_F(MultiIndexBlockTest, DoNotWriteStateToContainerOnSpillWhenNotResumable) { WriteUnitOfWork wuow(operationContext()); std::string val(64 * 1024, 'a'); for (auto i = 0; i < 20; ++i) { - ASSERT_OK(Helpers::insert(operationContext(), *autoColl, BSON("_id" << i << "a" << val))); + ASSERT_OK(Helpers::insert(operationContext(), coll.get(), BSON("_id" << i << "a" << val))); } wuow.commit(); @@ -3143,8 +3327,12 @@ TEST_F(MultiIndexBlockTest, AllSpillsDuringScanPersistScanPhase) { auto& observer = installResumeStateContainerObserver(operationContext()); auto& indexer = *getIndexer(); - AutoGetCollection autoColl{operationContext(), getNSS(), MODE_X}; - CollectionWriter coll{operationContext(), autoColl}; + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll{operationContext(), &acq}; auto buildUUID = UUID::gen(); indexer.setBuildUUID(buildUUID); @@ -3157,7 +3345,7 @@ TEST_F(MultiIndexBlockTest, AllSpillsDuringScanPersistScanPhase) { std::string val(64 * 1024, 'a'); for (auto i = 0; i < 300; ++i) { ASSERT_OK( - Helpers::insert(operationContext(), *autoColl, BSON("_id" << i << "a" << val))); + Helpers::insert(operationContext(), coll.get(), BSON("_id" << i << "a" << val))); } wuow.commit(); } @@ -3217,8 +3405,12 @@ TEST_F(MultiIndexBlockTest, LoadWritesResumeStatePeriodicallyForPrimaryDrivenBui auto& observer = installResumeStateContainerObserver(operationContext()); auto& indexer = *getIndexer(); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto buildUUID = UUID::gen(); indexer.setBuildUUID(buildUUID); @@ -3228,7 +3420,7 @@ TEST_F(MultiIndexBlockTest, LoadWritesResumeStatePeriodicallyForPrimaryDrivenBui WriteUnitOfWork wuow(operationContext()); for (auto i = 0; i < 50; ++i) { - ASSERT_OK(Helpers::insert(operationContext(), *autoColl, BSON("_id" << i << "a" << i))); + ASSERT_OK(Helpers::insert(operationContext(), coll.get(), BSON("_id" << i << "a" << i))); } wuow.commit(); @@ -3298,8 +3490,12 @@ TEST_F(MultiIndexBlockTest, LoadDoesNotPeriodicallyWriteWhenNotResumable) { auto& observer = installResumeStateContainerObserver(operationContext()); auto& indexer = *getIndexer(); - AutoGetCollection autoColl(operationContext(), getNSS(), MODE_X); - CollectionWriter coll(operationContext(), autoColl); + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll(operationContext(), &acq); auto buildUUID = UUID::gen(); indexer.setBuildUUID(buildUUID); @@ -3309,7 +3505,7 @@ TEST_F(MultiIndexBlockTest, LoadDoesNotPeriodicallyWriteWhenNotResumable) { WriteUnitOfWork wuow(operationContext()); for (auto i = 0; i < 50; ++i) { - ASSERT_OK(Helpers::insert(operationContext(), *autoColl, BSON("_id" << i << "a" << i))); + ASSERT_OK(Helpers::insert(operationContext(), coll.get(), BSON("_id" << i << "a" << i))); } wuow.commit(); @@ -3355,8 +3551,12 @@ TEST_F(MultiIndexBlockTest, LastSpilledRecordIdIsNotPersistedDuringLoadPhase) { auto& observer = installResumeStateContainerObserver(operationContext()); auto& indexer = *getIndexer(); - AutoGetCollection autoColl{operationContext(), getNSS(), MODE_X}; - CollectionWriter coll{operationContext(), autoColl}; + auto acq = + acquireCollection(operationContext(), + CollectionAcquisitionRequest::fromOpCtx( + operationContext(), getNSS(), AcquisitionPrerequisites::kWrite), + MODE_X); + CollectionWriter coll{operationContext(), &acq}; auto buildUUID = UUID::gen(); indexer.setBuildUUID(buildUUID); @@ -3367,7 +3567,7 @@ TEST_F(MultiIndexBlockTest, LastSpilledRecordIdIsNotPersistedDuringLoadPhase) { WriteUnitOfWork wuow{operationContext()}; std::string val(16 * 1024, 'a'); for (auto i = 0; i < 50; ++i) { - ASSERT_OK(Helpers::insert(operationContext(), *autoColl, BSON("_id" << i << "a" << val))); + ASSERT_OK(Helpers::insert(operationContext(), coll.get(), BSON("_id" << i << "a" << val))); } wuow.commit();