summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMisha Tyulenev <misha@mongodb.com>2018-04-12 20:42:21 -0400
committerMisha Tyulenev <misha@mongodb.com>2018-04-12 20:42:39 -0400
commitb7b55e75bbf18bcd7e38fdee430e0fd972183f68 (patch)
treee773e93083c2b4ed6580a3e98261db724f845021 /src
parent8c59201055adc886541c42b53e72a8b70963ec4a (diff)
downloadmongo-b7b55e75bbf18bcd7e38fdee430e0fd972183f68.tar.gz
SERVER-32639 skip signing and validating clusterTime in arbiters
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/logical_clock.cpp13
-rw-r--r--src/mongo/db/logical_clock.h15
-rw-r--r--src/mongo/db/logical_time_metadata_hook.cpp5
-rw-r--r--src/mongo/db/logical_time_validator.cpp14
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.cpp8
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp10
-rw-r--r--src/mongo/db/service_entry_point_common.cpp26
-rw-r--r--src/mongo/rpc/metadata.cpp2
8 files changed, 69 insertions, 24 deletions
diff --git a/src/mongo/db/logical_clock.cpp b/src/mongo/db/logical_clock.cpp
index d8e4d097ef4..a9b7cd62485 100644
--- a/src/mongo/db/logical_clock.cpp
+++ b/src/mongo/db/logical_clock.cpp
@@ -98,6 +98,7 @@ LogicalTime LogicalClock::getClusterTime() {
Status LogicalClock::advanceClusterTime(const LogicalTime newTime) {
stdx::lock_guard<stdx::mutex> lock(_mutex);
+ invariant(_isEnabled);
auto rateLimitStatus = _passesRateLimiter_inlock(newTime);
if (!rateLimitStatus.isOK()) {
@@ -116,6 +117,7 @@ LogicalTime LogicalClock::reserveTicks(uint64_t nTicks) {
invariant(nTicks > 0 && nTicks <= kMaxSignedInt);
stdx::lock_guard<stdx::mutex> lock(_mutex);
+ invariant(_isEnabled);
LogicalTime clusterTime = _clusterTime;
@@ -159,7 +161,6 @@ LogicalTime LogicalClock::reserveTicks(uint64_t nTicks) {
void LogicalClock::setClusterTimeFromTrustedSource(LogicalTime newTime) {
stdx::lock_guard<stdx::mutex> lock(_mutex);
-
// Rate limit checks are skipped here so a server with no activity for longer than
// maxAcceptableLogicalClockDriftSecs seconds can still have its cluster time initialized.
@@ -194,4 +195,14 @@ Status LogicalClock::_passesRateLimiter_inlock(LogicalTime newTime) {
return Status::OK();
}
+bool LogicalClock::isEnabled() const {
+ stdx::lock_guard<stdx::mutex> lock(_mutex);
+ return _isEnabled;
+}
+
+void LogicalClock::setEnabled(bool isEnabled) {
+ stdx::lock_guard<stdx::mutex> lock(_mutex);
+ _isEnabled = isEnabled;
+}
+
} // namespace mongo
diff --git a/src/mongo/db/logical_clock.h b/src/mongo/db/logical_clock.h
index 2408e03439b..fc662eb78ad 100644
--- a/src/mongo/db/logical_clock.h
+++ b/src/mongo/db/logical_clock.h
@@ -82,6 +82,16 @@ public:
*/
void setClusterTimeFromTrustedSource(LogicalTime newTime);
+ /**
+ * Returns true if the clock is enabled and can be used.
+ */
+ bool isEnabled() const;
+
+ /**
+ * Passing "true" enables the clock.
+ */
+ void setEnabled(bool isEnabled);
+
private:
/**
* Rate limiter for advancing cluster time. Rejects newTime if its seconds value is more than
@@ -91,9 +101,10 @@ private:
ServiceContext* const _service;
- // The mutex protects _clusterTime.
- stdx::mutex _mutex;
+ // The mutex protects _clusterTime and _isEnabled.
+ mutable stdx::mutex _mutex;
LogicalTime _clusterTime;
+ bool _isEnabled{true};
};
} // namespace mongo
diff --git a/src/mongo/db/logical_time_metadata_hook.cpp b/src/mongo/db/logical_time_metadata_hook.cpp
index 45abdb8efb6..ba84204f76e 100644
--- a/src/mongo/db/logical_time_metadata_hook.cpp
+++ b/src/mongo/db/logical_time_metadata_hook.cpp
@@ -48,7 +48,7 @@ LogicalTimeMetadataHook::LogicalTimeMetadataHook(ServiceContext* service) : _ser
Status LogicalTimeMetadataHook::writeRequestMetadata(OperationContext* opCtx,
BSONObjBuilder* metadataBob) {
auto validator = LogicalTimeValidator::get(_service);
- if (!validator) {
+ if (!validator || !LogicalClock::get(_service)->isEnabled()) {
return Status::OK();
}
@@ -70,7 +70,8 @@ Status LogicalTimeMetadataHook::readReplyMetadata(OperationContext* opCtx,
// LogicalTimeMetadata is default constructed if no cluster time metadata was sent, so a
// default constructed SignedLogicalTime should be ignored.
- if (signedTime.getTime() == LogicalTime::kUninitialized) {
+ if (signedTime.getTime() == LogicalTime::kUninitialized ||
+ !LogicalClock::get(_service)->isEnabled()) {
return Status::OK();
}
diff --git a/src/mongo/db/logical_time_validator.cpp b/src/mongo/db/logical_time_validator.cpp
index 085aef29e50..0bdf9cf1b24 100644
--- a/src/mongo/db/logical_time_validator.cpp
+++ b/src/mongo/db/logical_time_validator.cpp
@@ -171,7 +171,10 @@ void LogicalTimeValidator::init(ServiceContext* service) {
}
void LogicalTimeValidator::shutDown() {
- _getKeyManagerCopy()->stopMonitoring();
+ stdx::lock_guard<stdx::mutex> lk(_mutexKeyManager);
+ if (_keyManager) {
+ _keyManager->stopMonitoring();
+ }
}
void LogicalTimeValidator::enableKeyGenerator(OperationContext* opCtx, bool doEnable) {
@@ -192,11 +195,10 @@ bool LogicalTimeValidator::shouldGossipLogicalTime() {
void LogicalTimeValidator::resetKeyManagerCache() {
log() << "Resetting key manager cache";
- if (auto keyManager = _getKeyManagerCopy()) {
- keyManager->clearCache();
- _lastSeenValidTime = SignedLogicalTime();
- _timeProofService.resetCache();
- }
+ // TODO: SERVER-34445
+ _getKeyManagerCopy()->clearCache();
+ _lastSeenValidTime = SignedLogicalTime();
+ _timeProofService.resetCache();
}
void LogicalTimeValidator::resetKeyManager() {
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp
index 761747a6135..fdc733fe07c 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl.cpp
@@ -44,6 +44,7 @@
#include "mongo/db/index/index_descriptor.h"
#include "mongo/db/logical_clock.h"
#include "mongo/db/logical_time.h"
+#include "mongo/db/logical_time_validator.h"
#include "mongo/db/operation_context_noop.h"
#include "mongo/db/repl/check_quorum_for_config_change.h"
#include "mongo/db/repl/data_replicator_external_state_initial_sync.h"
@@ -563,6 +564,13 @@ void ReplicationCoordinatorImpl::_finishLoadLocalConfig(
} else {
lastOpTime = lastOpTimeStatus.getValue();
}
+ } else {
+ // The node is an arbiter hence will not need logical clock for external operations.
+ LogicalClock::get(getServiceContext())->setEnabled(false);
+ auto validator = LogicalTimeValidator::get(getServiceContext());
+ if (validator) {
+ validator->resetKeyManager();
+ }
}
long long term = OpTime::kUninitializedTerm;
diff --git a/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp b/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp
index 53e8fba916a..a73bad469fd 100644
--- a/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl_heartbeat.cpp
@@ -35,6 +35,8 @@
#include <algorithm>
#include "mongo/base/status.h"
+#include "mongo/db/logical_clock.h"
+#include "mongo/db/logical_time_validator.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/repl/elect_cmd_runner.h"
#include "mongo/db/repl/freshness_checker.h"
@@ -520,6 +522,14 @@ void ReplicationCoordinatorImpl::_heartbeatReconfigStore(
bool isArbiter = myIndex.isOK() && myIndex.getValue() != -1 &&
newConfig.getMemberAt(myIndex.getValue()).isArbiter();
+
+ if (isArbiter) {
+ LogicalClock::get(getGlobalServiceContext())->setEnabled(false);
+ if (auto validator = LogicalTimeValidator::get(getGlobalServiceContext())) {
+ validator->resetKeyManager();
+ }
+ }
+
if (!isArbiter && isFirstConfig) {
shouldStartDataReplication = true;
}
diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp
index 02431e9e396..0effad2301f 100644
--- a/src/mongo/db/service_entry_point_common.cpp
+++ b/src/mongo/db/service_entry_point_common.cpp
@@ -277,7 +277,7 @@ void appendReplyMetadataOnError(OperationContext* opCtx, BSONObjBuilder* metadat
const bool isReplSet =
replCoord->getReplicationMode() == repl::ReplicationCoordinator::modeReplSet;
- if (isReplSet) {
+ if (isReplSet && LogicalClock::get(opCtx)->isEnabled()) {
if (LogicalTimeValidator::isAuthorizedToAdvanceClock(opCtx)) {
// No need to sign cluster times for internal clients.
SignedLogicalTime currentTime(
@@ -323,19 +323,21 @@ void appendReplyMetadata(OperationContext* opCtx,
.writeToMetadata(metadataBob)
.transitional_ignore();
}
- if (LogicalTimeValidator::isAuthorizedToAdvanceClock(opCtx)) {
- // No need to sign cluster times for internal clients.
- SignedLogicalTime currentTime(
- LogicalClock::get(opCtx)->getClusterTime(), TimeProofService::TimeProof(), 0);
- rpc::LogicalTimeMetadata logicalTimeMetadata(currentTime);
- logicalTimeMetadata.writeToMetadata(metadataBob);
- } else if (auto validator = LogicalTimeValidator::get(opCtx)) {
- auto currentTime =
- validator->trySignLogicalTime(LogicalClock::get(opCtx)->getClusterTime());
- // Do not add $clusterTime if the signature and keyId is dummy.
- if (currentTime.getKeyId() != 0) {
+ if (LogicalClock::get(opCtx)->isEnabled()) {
+ if (LogicalTimeValidator::isAuthorizedToAdvanceClock(opCtx)) {
+ // No need to sign cluster times for internal clients.
+ SignedLogicalTime currentTime(
+ LogicalClock::get(opCtx)->getClusterTime(), TimeProofService::TimeProof(), 0);
rpc::LogicalTimeMetadata logicalTimeMetadata(currentTime);
logicalTimeMetadata.writeToMetadata(metadataBob);
+ } else if (auto validator = LogicalTimeValidator::get(opCtx)) {
+ auto currentTime =
+ validator->trySignLogicalTime(LogicalClock::get(opCtx)->getClusterTime());
+ // Do not add $clusterTime if the signature and keyId is dummy.
+ if (currentTime.getKeyId() != 0) {
+ rpc::LogicalTimeMetadata logicalTimeMetadata(currentTime);
+ logicalTimeMetadata.writeToMetadata(metadataBob);
+ }
}
}
diff --git a/src/mongo/rpc/metadata.cpp b/src/mongo/rpc/metadata.cpp
index 7373dc62172..6fd398a466f 100644
--- a/src/mongo/rpc/metadata.cpp
+++ b/src/mongo/rpc/metadata.cpp
@@ -90,7 +90,7 @@ void readRequestMetadata(OperationContext* opCtx, const BSONObj& metadataObj) {
uassertStatusOK(TrackingMetadata::readFromMetadata(trackingElem));
auto logicalClock = LogicalClock::get(opCtx);
- if (logicalClock) {
+ if (logicalClock && logicalClock->isEnabled()) {
auto logicalTimeMetadata =
uassertStatusOK(rpc::LogicalTimeMetadata::readFromMetadata(logicalTimeElem));