The consequence is that other collection instances that have this IndexCatalogEntry can observe changes from other operations that make changes to the IndexCatalogEntry.
TEST_F(CollectionCatalogTimestampTest, IndexCatalogEntryCopying) {
const NamespaceString nss("test.abc");
createCollection(opCtx.get(), nss, Timestamp::min());
IndexCatalogEntry* entry;
{
// Start but do not finish an index build.
IndexSpec spec;
spec.version(1).name("x_1").addKeys(BSON("x" << 1));
auto desc = std::make_unique<IndexDescriptor>(IndexNames::BTREE, spec.toBSON());
AutoGetCollection autoColl(opCtx.get(), nss, MODE_X);
WriteUnitOfWork wuow(opCtx.get());
auto collWriter = autoColl.getWritableCollection(opCtx.get());
ASSERT_OK(collWriter->prepareForIndexBuild(opCtx.get(), desc.get(), boost::none, false));
entry = collWriter->getIndexCatalog()->createIndexEntry(
opCtx.get(), collWriter, std::move(desc), CreateIndexEntryFlags::kNone);
wuow.commit();
}
// In a different client, open the latest collection instance of 'nss'
auto newClient = opCtx->getServiceContext()->makeClient("alternativeClient");
auto newOpCtx = newClient->makeOperationContext();
auto latestCatalog = CollectionCatalog::latest(newOpCtx.get());
auto latestColl =
latestCatalog->establishConsistentCollection(newOpCtx.get(), nss, boost::none);
ASSERT_EQ(1, latestColl->getIndexCatalog()->numIndexesTotal());
ASSERT_EQ(0, latestColl->getIndexCatalog()->numIndexesReady());
ASSERT_EQ(1, latestColl->getIndexCatalog()->numIndexesInProgress());
// The index is NOT ready.
auto descLatestBefore = latestColl->getIndexCatalog()->findIndexByName(
newOpCtx.get(),
"x_1",
IndexCatalog::InclusionPolicy::kReady | IndexCatalog::InclusionPolicy::kFrozen |
IndexCatalog::InclusionPolicy::kUnfinished);
auto entryLatestBefore = latestColl->getIndexCatalog()->getEntry(descLatestBefore);
ASSERT(!entryLatestBefore->isReady());
{
// Now finish the index build on the original OperationContext.
AutoGetCollection autoColl(opCtx.get(), nss, MODE_X);
WriteUnitOfWork wuow(opCtx.get());
auto collWriter = autoColl.getWritableCollection(opCtx.get());
collWriter->getIndexCatalog()->indexBuildSuccess(opCtx.get(), collWriter, entry);
wuow.commit();
}
// Container counts are still correct.
ASSERT_EQ(1, latestColl->getIndexCatalog()->numIndexesTotal());
ASSERT_EQ(0, latestColl->getIndexCatalog()->numIndexesReady());
ASSERT_EQ(1, latestColl->getIndexCatalog()->numIndexesInProgress());
// But the index is marked as ready now. When the collection clone happened above, it made a
// copy of the containers, which is std::vector<std::shared_ptr<IndexCatalogEntry>> so we only
// upped the ref count.
auto descLatestAfter = latestColl->getIndexCatalog()->findIndexByName(
newOpCtx.get(),
"x_1",
IndexCatalog::InclusionPolicy::kReady | IndexCatalog::InclusionPolicy::kFrozen |
IndexCatalog::InclusionPolicy::kUnfinished);
auto entryLatestAfter = latestColl->getIndexCatalog()->getEntry(descLatestAfter);
ASSERT(!entryLatestAfter->isReady());
}
- causes
-
SERVER-77842 Cache IndexCatalogEntry during the collection scan phase of an index build
-
- Closed
-
- is depended on by
-
SERVER-77131 Remove and ban any write to collection instance in commit handlers
-
- Closed
-
- is related to
-
SERVER-77368 Remove const_cast<IndexAccessMethod*> in KeyStringIndexConsistency constructor
-
- Closed
-
-
SERVER-77379 Cleanup IndexCatalogImpl::_deleteIndexFromDisk() code path to use const IndexCatalogEntry instead of shared_ptr
-
- Closed
-
- related to
-
SERVER-77082 Data race while setting index build interceptor on empty coll optimization path
-
- Closed
-