summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/replsets/initial_sync_replSetGetStatus.js14
-rw-r--r--src/mongo/db/repl/initial_syncer.cpp29
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);
+ }
}
}