@@ -2298,6 +2298,90 @@ class TimestampMultiIndexBuildsDuringRename : public StorageTimestampTest {
22982298 }
22992299};
23002300
2301+ /* *
2302+ * This test asserts that the catalog updates that represent the beginning and end of an aborted
2303+ * index build are timestamped. The oplog should contain two entries startIndexBuild and
2304+ * abortIndexBuild. We will inspect the catalog at the timestamp corresponding to each of these
2305+ * oplog entries.
2306+ */
2307+ class TimestampAbortIndexBuild : public StorageTimestampTest {
2308+ public:
2309+ void run () {
2310+ auto storageEngine = _opCtx->getServiceContext ()->getStorageEngine ();
2311+ auto durableCatalog = storageEngine->getCatalog ();
2312+
2313+ NamespaceString nss (" unittests.timestampAbortIndexBuild" );
2314+ reset (nss);
2315+
2316+ std::vector<std::string> origIdents;
2317+ {
2318+ AutoGetCollection autoColl (_opCtx, nss, LockMode::MODE_X);
2319+
2320+ auto insertTimestamp1 = _clock->reserveTicks (1 );
2321+ auto insertTimestamp2 = _clock->reserveTicks (1 );
2322+
2323+ // Insert two documents with the same value for field 'a' so that
2324+ // we will fail to create a unique index.
2325+ WriteUnitOfWork wuow (_opCtx);
2326+ insertDocument (autoColl.getCollection (),
2327+ InsertStatement (BSON (" _id" << 0 << " a" << 1 ),
2328+ insertTimestamp1.asTimestamp (),
2329+ presentTerm));
2330+ insertDocument (autoColl.getCollection (),
2331+ InsertStatement (BSON (" _id" << 1 << " a" << 1 ),
2332+ insertTimestamp2.asTimestamp (),
2333+ presentTerm));
2334+ wuow.commit ();
2335+ ASSERT_EQ (2 , itCount (autoColl.getCollection ()));
2336+
2337+ // Save the pre-state idents so we can capture the specific ident related to index
2338+ // creation.
2339+ origIdents = durableCatalog->getAllIdents (_opCtx);
2340+ }
2341+
2342+ {
2343+ DBDirectClient client (_opCtx);
2344+
2345+ IndexSpec index1;
2346+ // Name this index for easier querying.
2347+ index1.addKeys (BSON (" a" << 1 )).name (" a_1" ).unique ();
2348+
2349+ std::vector<const IndexSpec*> indexes;
2350+ indexes.push_back (&index1);
2351+ ASSERT_THROWS_CODE (
2352+ client.createIndexes (nss.ns (), indexes), DBException, ErrorCodes::DuplicateKey);
2353+ }
2354+
2355+ // Confirm that startIndexBuild and abortIndexBuild oplog entries have been written to the
2356+ // oplog.
2357+ auto indexStartDocument =
2358+ queryOplog (BSON (" ns" << nss.db () + " .$cmd"
2359+ << " o.startIndexBuild" << nss.coll () << " o.indexes.0.name"
2360+ << " a_1" ));
2361+ auto indexStartTs = indexStartDocument[" ts" ].timestamp ();
2362+ auto indexAbortDocument =
2363+ queryOplog (BSON (" ns" << nss.db () + " .$cmd"
2364+ << " o.abortIndexBuild" << nss.coll () << " o.indexes.0.name"
2365+ << " a_1" ));
2366+ auto indexAbortTs = indexAbortDocument[" ts" ].timestamp ();
2367+
2368+ // Check index state in catalog at oplog entry times for both startIndexBuild and
2369+ // abortIndexBuild.
2370+ AutoGetCollection autoColl (_opCtx, nss, LockMode::MODE_X);
2371+
2372+ // We expect one new one new index ident during this index build.
2373+ assertRenamedCollectionIdentsAtTimestamp (
2374+ durableCatalog, origIdents, /* expectedNewIndexIdents*/ 1 , indexStartTs);
2375+ ASSERT_FALSE (
2376+ getIndexMetaData (getMetaDataAtTime (durableCatalog, nss, indexStartTs), " a_1" ).ready );
2377+
2378+ // We expect all new idents to be removed after the index build has aborted.
2379+ assertRenamedCollectionIdentsAtTimestamp (
2380+ durableCatalog, origIdents, /* expectedNewIndexIdents*/ 0 , indexAbortTs);
2381+ assertIndexMetaDataMissing (getMetaDataAtTime (durableCatalog, nss, indexAbortTs), " a_1" );
2382+ }
2383+ };
2384+
23012385class TimestampIndexDrops : public StorageTimestampTest {
23022386public:
23032387 void run () {
@@ -3480,6 +3564,7 @@ class AllStorageTimestampTests : public unittest::OldStyleSuiteSpecification {
34803564 // addIf<TimestampIndexBuildDrain<true>>();
34813565 addIf<TimestampMultiIndexBuilds>();
34823566 addIf<TimestampMultiIndexBuildsDuringRename>();
3567+ addIf<TimestampAbortIndexBuild>();
34833568 addIf<TimestampIndexDrops>();
34843569 addIf<TimestampIndexBuilderOnPrimary>();
34853570 addIf<SecondaryReadsDuringBatchApplicationAreAllowed>();
0 commit comments