summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/db/repl/initial_syncer.cpp18
-rw-r--r--src/mongo/db/repl/storage_interface.h7
-rw-r--r--src/mongo/db/repl/storage_interface_impl.cpp5
-rw-r--r--src/mongo/db/repl/storage_interface_impl.h2
-rw-r--r--src/mongo/db/repl/storage_interface_mock.h4
5 files changed, 30 insertions, 6 deletions
diff --git a/src/mongo/db/repl/initial_syncer.cpp b/src/mongo/db/repl/initial_syncer.cpp
index 0cf95dfe417..9c77306ef0b 100644
--- a/src/mongo/db/repl/initial_syncer.cpp
+++ b/src/mongo/db/repl/initial_syncer.cpp
@@ -802,6 +802,7 @@ void InitialSyncer::_lastOplogEntryFetcherCallbackForStopTimestamp(
const StatusWith<Fetcher::QueryResponse>& result,
std::shared_ptr<OnCompletionGuard> onCompletionGuard) {
Timestamp oplogSeedDocTimestamp;
+ OpTimeWithHash optimeWithHash;
{
stdx::lock_guard<stdx::mutex> lock(_mutex);
auto status = _checkForShutdownAndConvertStatus_inlock(
@@ -817,15 +818,11 @@ void InitialSyncer::_lastOplogEntryFetcherCallbackForStopTimestamp(
lock, optimeWithHashStatus.getStatus());
return;
}
- auto&& optimeWithHash = optimeWithHashStatus.getValue();
+ optimeWithHash = optimeWithHashStatus.getValue();
oplogSeedDocTimestamp = _initialSyncState->stopTimestamp =
optimeWithHash.opTime.getTimestamp();
- if (_initialSyncState->beginTimestamp == _initialSyncState->stopTimestamp) {
- _lastApplied = optimeWithHash;
- log() << "No need to apply operations. (currently at "
- << _initialSyncState->stopTimestamp.toBSON() << ")";
- } else {
+ if (_initialSyncState->beginTimestamp != _initialSyncState->stopTimestamp) {
invariant(_lastApplied.opTime.isNull());
_checkApplierProgressAndScheduleGetNextApplierBatch_inlock(lock, onCompletionGuard);
return;
@@ -854,9 +851,18 @@ void InitialSyncer::_lastOplogEntryFetcherCallbackForStopTimestamp(
onCompletionGuard->setResultAndCancelRemainingWork_inlock(lock, status);
return;
}
+
+ // This is necessary to ensure that the seed doc is visible in the oplog prior to setting
+ // _lastApplied. That way if any other node attempts to read from this node's oplog, it
+ // won't appear empty.
+ _storage->waitForAllEarlierOplogWritesToBeVisible(opCtx.get());
}
stdx::lock_guard<stdx::mutex> lock(_mutex);
+ _lastApplied = optimeWithHash;
+ log() << "No need to apply operations. (currently at "
+ << _initialSyncState->stopTimestamp.toBSON() << ")";
+
// This sets the error in 'onCompletionGuard' and shuts down the OplogFetcher on error.
_scheduleRollbackCheckerCheckForRollback_inlock(lock, onCompletionGuard);
}
diff --git a/src/mongo/db/repl/storage_interface.h b/src/mongo/db/repl/storage_interface.h
index 27507e790e8..840b40e2c16 100644
--- a/src/mongo/db/repl/storage_interface.h
+++ b/src/mongo/db/repl/storage_interface.h
@@ -305,6 +305,13 @@ public:
* The 'stable' timestamp is set by calling StorageInterface::setStableTimestamp.
*/
virtual Status recoverToStableTimestamp(ServiceContext* serviceCtx) = 0;
+
+ /**
+ * Waits for oplog writes to be visible in the oplog.
+ * This function is used to ensure tests do not fail due to initial sync receiving an empty
+ * batch.
+ */
+ virtual void waitForAllEarlierOplogWritesToBeVisible(OperationContext* opCtx) = 0;
};
} // namespace repl
diff --git a/src/mongo/db/repl/storage_interface_impl.cpp b/src/mongo/db/repl/storage_interface_impl.cpp
index 35e67cbbe9f..db090542ed6 100644
--- a/src/mongo/db/repl/storage_interface_impl.cpp
+++ b/src/mongo/db/repl/storage_interface_impl.cpp
@@ -967,5 +967,10 @@ Status StorageInterfaceImpl::isAdminDbValid(OperationContext* opCtx) {
return Status::OK();
}
+void StorageInterfaceImpl::waitForAllEarlierOplogWritesToBeVisible(OperationContext* opCtx) {
+ AutoGetCollection oplog(opCtx, NamespaceString::kRsOplogNamespace, MODE_IS);
+ oplog.getCollection()->getRecordStore()->waitForAllEarlierOplogWritesToBeVisible(opCtx);
+}
+
} // namespace repl
} // namespace mongo
diff --git a/src/mongo/db/repl/storage_interface_impl.h b/src/mongo/db/repl/storage_interface_impl.h
index 572cf4eb992..2b8ba24f022 100644
--- a/src/mongo/db/repl/storage_interface_impl.h
+++ b/src/mongo/db/repl/storage_interface_impl.h
@@ -145,6 +145,8 @@ public:
*/
Status isAdminDbValid(OperationContext* opCtx) override;
+ void waitForAllEarlierOplogWritesToBeVisible(OperationContext* opCtx) override;
+
private:
const NamespaceString _rollbackIdNss;
};
diff --git a/src/mongo/db/repl/storage_interface_mock.h b/src/mongo/db/repl/storage_interface_mock.h
index 7526acfafa8..a0cd570cf8d 100644
--- a/src/mongo/db/repl/storage_interface_mock.h
+++ b/src/mongo/db/repl/storage_interface_mock.h
@@ -260,6 +260,10 @@ public:
return isAdminDbValidFn(opCtx);
};
+ void waitForAllEarlierOplogWritesToBeVisible(OperationContext* opCtx) override {
+ return;
+ }
+
// Testing functions.
CreateCollectionForBulkFn createCollectionForBulkFn =
[](const NamespaceString& nss,