@@ -2298,6 +2298,90 @@ class TimestampMultiIndexBuildsDuringRename : public StorageTimestampTest {
2298
2298
}
2299
2299
};
2300
2300
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
+
2301
2385
class TimestampIndexDrops : public StorageTimestampTest {
2302
2386
public:
2303
2387
void run () {
@@ -3480,6 +3564,7 @@ class AllStorageTimestampTests : public unittest::OldStyleSuiteSpecification {
3480
3564
// addIf<TimestampIndexBuildDrain<true>>();
3481
3565
addIf<TimestampMultiIndexBuilds>();
3482
3566
addIf<TimestampMultiIndexBuildsDuringRename>();
3567
+ addIf<TimestampAbortIndexBuild>();
3483
3568
addIf<TimestampIndexDrops>();
3484
3569
addIf<TimestampIndexBuilderOnPrimary>();
3485
3570
addIf<SecondaryReadsDuringBatchApplicationAreAllowed>();
0 commit comments