From 63ffb50b2889c9d60a506dc0e8a1071c3ac39e36 Mon Sep 17 00:00:00 2001 From: Josef Ahmad Date: Fri, 5 May 2023 09:21:15 +0000 Subject: [PATCH] SERVER-74953 reproducer --- jstests/noPassthrough/repro-server-74953.js | 51 +++++++++++++++++++++ src/mongo/db/index_builds_coordinator.cpp | 4 ++ 2 files changed, 55 insertions(+) create mode 100644 jstests/noPassthrough/repro-server-74953.js diff --git a/jstests/noPassthrough/repro-server-74953.js b/jstests/noPassthrough/repro-server-74953.js new file mode 100644 index 00000000000..b04820f9a6b --- /dev/null +++ b/jstests/noPassthrough/repro-server-74953.js @@ -0,0 +1,51 @@ +/** + * Starts an index build, simulating a slow setup condition, and steps down the primary. If the + * startIndexBuild has not yet been replicated, the build should be killed while stepping down. + * Otherwise, we are in an inconsistent state, where the new primary can drop the collection (which + * has no active builds) and cause the secondary to detect an active build before dropping the + * collection. + * + * @tags: [ + * requires_replication, + * ] + */ +(function() { +'use strict'; + +load('jstests/libs/fail_point_util.js'); +load('jstests/noPassthrough/libs/index_build.js'); + +const rst = new ReplSetTest({nodes: 2}); +rst.startSet(); +rst.initiate(); + +const primary = rst.getPrimary(); +const primaryDB = primary.getDB('test'); +const primaryColl = primaryDB.getCollection('coll'); + +assert.commandWorked(primaryColl.insert({_id: 1, a: 1})); + +// Enable fail point which makes index build hang during setup, simulating a condition where the +// index build is registered, but not yet replicated. +const failPoint = configureFailPoint(primary, 'hangIndexBuildOnSetupBeforeTakingLocks'); + +const createIndex = IndexBuildTest.startIndexBuild( + primary, primaryColl.getFullName(), {a: 1}, {}, [ErrorCodes.InterruptedDueToReplStateChange]); + +failPoint.wait(); + +assert.commandWorked(primaryDB.adminCommand({"replSetStepDown": 5 * 60, "force": true})); + +const newPrimary = rst.getPrimary(); +const newPrimaryDB = newPrimary.getDB('test'); +const newPrimaryColl = newPrimaryDB.getCollection('coll'); + +// Drop the collection on the new primary. If the index build on the old primary was not properly +// aborted on step-down, the node will crash while applying the drop. +newPrimaryColl.drop(); + +rst.awaitReplication(); +createIndex(); + +rst.stopSet(); +})(); diff --git a/src/mongo/db/index_builds_coordinator.cpp b/src/mongo/db/index_builds_coordinator.cpp index 8051f89ec36..1ef869661de 100644 --- a/src/mongo/db/index_builds_coordinator.cpp +++ b/src/mongo/db/index_builds_coordinator.cpp @@ -95,6 +95,7 @@ MONGO_FAIL_POINT_DEFINE(hangBeforeUnregisteringAfterCommit); MONGO_FAIL_POINT_DEFINE(failSetUpResumeIndexBuild); MONGO_FAIL_POINT_DEFINE(failIndexBuildWithError); MONGO_FAIL_POINT_DEFINE(hangInRemoveIndexBuildEntryAfterCommitOrAbort); +MONGO_FAIL_POINT_DEFINE(hangIndexBuildOnSetupBeforeTakingLocks); IndexBuildsCoordinator::IndexBuildsSSS::IndexBuildsSSS() : ServerStatusSection("indexBuilds"), @@ -2301,6 +2302,9 @@ IndexBuildsCoordinator::PostSetupAction IndexBuildsCoordinator::_setUpIndexBuild std::shared_ptr replState, Timestamp startTimestamp, const IndexBuildOptions& indexBuildOptions) { + + hangIndexBuildOnSetupBeforeTakingLocks.pauseWhileSet(opCtx); + auto [dbLock, collLock, rstl] = std::move(_acquireExclusiveLockWithRSTLRetry(opCtx, replState.get()).getValue()); -- 2.17.1