diff options
author | Benety Goh <benety@mongodb.com> | 2020-11-19 13:07:23 -0500 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-11-19 22:20:14 +0000 |
commit | 77554e9e4fd18811d6df84d8934c888814d034ec (patch) | |
tree | 2003d4df1d93d9adc40f406ffac96788f91a7fa0 | |
parent | 4739fb232284a655f0ae89c9a43490ed2219cb5e (diff) | |
download | mongo-77554e9e4fd18811d6df84d8934c888814d034ec.tar.gz |
SERVER-49249 initial sync skips single-phase index build if there is an index build already in progress
-rw-r--r-- | jstests/replsets/initial_sync_index_conflict.js | 10 | ||||
-rw-r--r-- | src/mongo/db/repl/oplog.cpp | 25 |
2 files changed, 27 insertions, 8 deletions
diff --git a/jstests/replsets/initial_sync_index_conflict.js b/jstests/replsets/initial_sync_index_conflict.js index c1af06307a1..b96c7f17176 100644 --- a/jstests/replsets/initial_sync_index_conflict.js +++ b/jstests/replsets/initial_sync_index_conflict.js @@ -67,19 +67,15 @@ try { // Resume initial sync. The createIndexes oplog entry will be applied. failPoint.off(); - assert.soon(function() { - return rawMongoProgramOutput().search( - /Invariant failure.*indexSpecs.size\(\) > 1.*test.coll.*a_1.*multi_index_block\.cpp/) >= - 0; - }); + // Wait for initial sync to finish. + rst.awaitSecondaryNodes(); } finally { + IndexBuildTest.resumeIndexBuilds(secondary); IndexBuildTest.resumeIndexBuilds(primary); createIdx(); } IndexBuildTest.assertIndexes(primaryColl, 2, ['_id_', 'a_1']); -rst.stop(secondary, undefined, {allowedExitCode: MongoRunner.EXIT_ABORT}); -TestData.skipCheckDBHashes = true; rst.stopSet(); })(); diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp index 1ea29defe74..d8c95789f04 100644 --- a/src/mongo/db/repl/oplog.cpp +++ b/src/mongo/db/repl/oplog.cpp @@ -194,6 +194,30 @@ void createIndexForApplyOps(OperationContext* opCtx, opCtx->getWriteConcern()); } + // Check for conflict with two-phase index builds during initial sync. It is possible that + // this index may have been dropped and recreated after inserting documents into the collection. + auto indexBuildsCoordinator = IndexBuildsCoordinator::get(opCtx); + if (OplogApplication::Mode::kInitialSync == mode) { + auto normalSpecs = + indexBuildsCoordinator->normalizeIndexSpecs(opCtx, indexCollection, {indexSpec}); + invariant(1U == normalSpecs.size(), + str::stream() << "Unexpected result from normalizeIndexSpecs - ns: " << indexNss + << "; uuid: " << indexCollection->uuid() + << "; original index spec: " << indexSpec + << "; normalized index specs: " + << BSON("normalSpecs" << normalSpecs)); + auto indexCatalog = indexCollection->getIndexCatalog(); + auto prepareSpecResult = indexCatalog->prepareSpecForCreate(opCtx, normalSpecs[0], {}); + if (ErrorCodes::IndexBuildAlreadyInProgress == prepareSpecResult) { + LOGV2(4924900, + "Index build: already in progress during initial sync", + "ns"_attr = indexNss, + "uuid"_attr = indexCollection->uuid(), + "spec"_attr = indexSpec); + return; + } + } + // TODO(SERVER-48593): Add invariant on shouldRelaxIndexConstraints(opCtx, indexNss) and // set constraints to kRelax. const auto constraints = @@ -205,7 +229,6 @@ void createIndexForApplyOps(OperationContext* opCtx, // stop using ghost timestamps. Single phase builds are only used for empty collections, and // to rebuild indexes admin.system collections. See SERVER-47439. IndexBuildsCoordinator::updateCurOpOpDescription(opCtx, indexNss, {indexSpec}); - auto indexBuildsCoordinator = IndexBuildsCoordinator::get(opCtx); auto collUUID = indexCollection->uuid(); auto fromMigrate = false; indexBuildsCoordinator->createIndex(opCtx, collUUID, indexSpec, constraints, fromMigrate); |