summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Russotto <matthew.russotto@mongodb.com>2021-10-25 14:27:53 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-11-01 21:53:16 +0000
commit8d6668dd678ca61668d41ceb3d0082290b429562 (patch)
treead2591cbbfec76bbd575be44a407a77b574f5bab
parent5d1078c60e8f24e027dc72d7ceeac4dab49908b9 (diff)
downloadmongo-8d6668dd678ca61668d41ceb3d0082290b429562.tar.gz
SERVER-60701 Block reads to local database from user connections while in File Copy Based Initial Sync
-rw-r--r--src/mongo/db/repl/initial_syncer.h4
-rw-r--r--src/mongo/db/repl/initial_syncer_interface.h6
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.cpp18
3 files changed, 28 insertions, 0 deletions
diff --git a/src/mongo/db/repl/initial_syncer.h b/src/mongo/db/repl/initial_syncer.h
index 566bde4919f..177122e12d9 100644
--- a/src/mongo/db/repl/initial_syncer.h
+++ b/src/mongo/db/repl/initial_syncer.h
@@ -162,6 +162,10 @@ public:
std::string getInitialSyncMethod() const final;
+ bool allowLocalDbAccess() const final {
+ return true;
+ }
+
Status startup(OperationContext* opCtx, std::uint32_t maxAttempts) noexcept final;
Status shutdown() final;
diff --git a/src/mongo/db/repl/initial_syncer_interface.h b/src/mongo/db/repl/initial_syncer_interface.h
index 9bf683e99b8..b4a787bbc94 100644
--- a/src/mongo/db/repl/initial_syncer_interface.h
+++ b/src/mongo/db/repl/initial_syncer_interface.h
@@ -121,6 +121,12 @@ public:
* Returns the initial sync method that this initial syncer is using.
*/
virtual std::string getInitialSyncMethod() const = 0;
+
+ /**
+ * Returns whether user access to db 'local' should be allowed during this initial sync.
+ * Should be constant, and must not take any locks.
+ */
+ virtual bool allowLocalDbAccess() const = 0;
};
} // namespace repl
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp
index 4e4d1fa1aac..8ab52737ad5 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl.cpp
@@ -2969,6 +2969,24 @@ Status ReplicationCoordinatorImpl::checkCanServeReadsFor_UNSAFE(OperationContext
}
}
+ // Non-oplog local reads from the user are not allowed during initial sync when the initial
+ // sync method disallows it. "isFromUserConnection" means DBDirectClient reads are not blocked;
+ // "isInternalClient" means reads from other cluster members are not blocked.
+ if (!isPrimaryOrSecondary && getReplicationMode() == modeReplSet && ns.db() == kLocalDB &&
+ client->isFromUserConnection()) {
+ stdx::lock_guard<Latch> lock(_mutex);
+ auto isInternalClient = !client->session() ||
+ (client->session()->getTags() & transport::Session::kInternalClient);
+ if (!isInternalClient && _memberState.startup2() && _initialSyncer &&
+ !_initialSyncer->allowLocalDbAccess()) {
+ return Status{ErrorCodes::NotPrimaryOrSecondary,
+ str::stream() << "Local reads are not allowed during initial sync with "
+ "current initial sync method: "
+ << _initialSyncer->getInitialSyncMethod()};
+ }
+ }
+
+
if (canAcceptWritesFor_UNSAFE(opCtx, ns)) {
return Status::OK();
}