diff options
-rw-r--r-- | jstests/replsets/initial_sync_replSetGetStatus.js | 14 | ||||
-rw-r--r-- | src/mongo/db/repl/initial_syncer.cpp | 29 |
2 files changed, 33 insertions, 10 deletions
diff --git a/jstests/replsets/initial_sync_replSetGetStatus.js b/jstests/replsets/initial_sync_replSetGetStatus.js index 8b1d7364e9d..19660877953 100644 --- a/jstests/replsets/initial_sync_replSetGetStatus.js +++ b/jstests/replsets/initial_sync_replSetGetStatus.js @@ -40,6 +40,8 @@ assert.commandWorked(secondary.getDB('admin').runCommand( {configureFailPoint: 'initialSyncHangBeforeCopyingDatabases', mode: 'alwaysOn'})); assert.commandWorked(secondary.getDB('admin').runCommand( {configureFailPoint: 'initialSyncHangBeforeFinish', mode: 'alwaysOn'})); +assert.commandWorked(secondary.getDB('admin').runCommand( + {configureFailPoint: 'initialSyncHangAfterFinish', mode: 'alwaysOn'})); replSet.reInitiate(); // Wait for initial sync to pause before it copies the databases. @@ -151,10 +153,12 @@ assert.eq(endOfCloningRes.initialSyncStatus.approxTotalDataSize, assert.eq(endOfCloningRes.initialSyncStatus.approxTotalBytesCopied, fooCollRes.approxBytesCopied + barCollRes.approxBytesCopied + bytesCopiedAdminDb); -// Let initial sync finish and get into secondary state. assert.commandWorked(secondary.getDB('admin').runCommand( {configureFailPoint: 'initialSyncHangBeforeFinish', mode: 'off'})); -replSet.awaitSecondaryNodes(60 * 1000); + +// Wait until the 'initialSync' field has been cleared before issuing 'replSetGetStatus'. +checkLog.contains(secondary, + "initial sync finished - initialSyncHangAfterFinish fail point enabled"); // Test that replSetGetStatus returns the correct results after initial sync is finished. res = assert.commandWorked(secondary.adminCommand({replSetGetStatus: 1})); @@ -163,6 +167,12 @@ assert(!res.initialSyncStatus, assert.commandFailedWithCode(secondary.adminCommand({replSetGetStatus: 1, initialSync: "m"}), ErrorCodes.TypeMismatch); + +// Let initial sync finish and get into secondary state. +assert.commandWorked(secondary.getDB('admin').runCommand( + {configureFailPoint: 'initialSyncHangAfterFinish', mode: 'off'})); +replSet.awaitSecondaryNodes(60 * 1000); + assert.eq(0, secondary.getDB('local')['temp_oplog_buffer'].find().itcount(), "Oplog buffer was not dropped after initial sync"); diff --git a/src/mongo/db/repl/initial_syncer.cpp b/src/mongo/db/repl/initial_syncer.cpp index a5386f9bc84..2ba982d5d12 100644 --- a/src/mongo/db/repl/initial_syncer.cpp +++ b/src/mongo/db/repl/initial_syncer.cpp @@ -117,6 +117,9 @@ MONGO_FAIL_POINT_DEFINE(initialSyncFassertIfApplyingBatchFails); // Failpoint which skips clearing _initialSyncState after a successful initial sync attempt. MONGO_FAIL_POINT_DEFINE(skipClearInitialSyncState); +// Failpoint which causes the initial sync function to hang after finishing. +MONGO_FAIL_POINT_DEFINE(initialSyncHangAfterFinish); + namespace { using namespace executor; using CallbackArgs = executor::TaskExecutor::CallbackArgs; @@ -1610,15 +1613,25 @@ void InitialSyncer::_finishCallback(StatusWith<OpTimeAndWallTime> lastApplied) { // before InitialSyncer::join() returns. onCompletion = {}; - stdx::lock_guard<Latch> lock(_mutex); - invariant(_state != State::kComplete); - _state = State::kComplete; - _stateCondition.notify_all(); + { + stdx::lock_guard<Latch> lock(_mutex); + invariant(_state != State::kComplete); + _state = State::kComplete; + _stateCondition.notify_all(); - // Clear the initial sync progress after an initial sync attempt has been successfully - // completed. - if (lastApplied.isOK() && !MONGO_FAIL_POINT(skipClearInitialSyncState)) { - _initialSyncState.reset(); + // Clear the initial sync progress after an initial sync attempt has been successfully + // completed. + if (lastApplied.isOK() && !MONGO_FAIL_POINT(skipClearInitialSyncState)) { + _initialSyncState.reset(); + } + } + + if (MONGO_FAIL_POINT(initialSyncHangAfterFinish)) { + log() << "initial sync finished - initialSyncHangAfterFinish fail point " + "enabled. Blocking until fail point is disabled."; + while (MONGO_FAIL_POINT(initialSyncHangAfterFinish) && !_isShuttingDown()) { + mongo::sleepsecs(1); + } } } |