summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/SConscript25
-rw-r--r--src/mongo/db/commands/getmore_cmd.cpp1
-rw-r--r--src/mongo/db/db.cpp5
-rw-r--r--src/mongo/db/global_timestamp.cpp94
-rw-r--r--src/mongo/db/logical_clock.cpp24
-rw-r--r--src/mongo/db/logical_clock.h9
-rw-r--r--src/mongo/db/logical_clock_test_fixture.cpp49
-rw-r--r--src/mongo/db/logical_clock_test_fixture.h (renamed from src/mongo/db/global_timestamp.h)29
-rw-r--r--src/mongo/db/logical_time_test.cpp2
-rw-r--r--src/mongo/db/ops/SConscript6
-rw-r--r--src/mongo/db/ops/insert.cpp6
-rw-r--r--src/mongo/db/ops/modifier_current_date.cpp8
-rw-r--r--src/mongo/db/ops/modifier_current_date_test.cpp29
-rw-r--r--src/mongo/db/ops/modifier_object_replace.cpp5
-rw-r--r--src/mongo/db/ops/modifier_object_replace_test.cpp32
-rw-r--r--src/mongo/db/repl/SConscript3
-rw-r--r--src/mongo/db/repl/oplog.cpp13
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.cpp13
-rw-r--r--src/mongo/db/repl/replication_coordinator_test_fixture.cpp7
-rw-r--r--src/mongo/db/repl/sync_tail.cpp1
-rw-r--r--src/mongo/db/s/balancer/migration_manager_test.cpp9
-rw-r--r--src/mongo/dbtests/SConscript1
-rw-r--r--src/mongo/dbtests/dbtests.cpp8
-rw-r--r--src/mongo/dbtests/querytests.cpp15
-rw-r--r--src/mongo/s/server.cpp7
-rw-r--r--src/mongo/s/sharding_mongod_test_fixture.cpp7
26 files changed, 234 insertions, 174 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript
index 91f6b2118bd..5aa01462143 100644
--- a/src/mongo/db/SConscript
+++ b/src/mongo/db/SConscript
@@ -243,17 +243,6 @@ env.CppUnitTest(
)
env.Library(
- target='global_timestamp',
- source=[
- 'global_timestamp.cpp',
- ],
- LIBDEPS=[
- '$BUILD_DIR/mongo/base',
- '$BUILD_DIR/mongo/db/service_context'
- ]
-)
-
-env.Library(
target='namespace_string',
source=[
'namespace_string.cpp',
@@ -881,7 +870,6 @@ env.Library(
"exec/working_set",
"fts/ftsmongod",
"ftdc/ftdc_mongod",
- "global_timestamp",
"index/index_descriptor",
"index/index_access_methods",
"index_d",
@@ -992,6 +980,19 @@ env.CppUnitTest(
)
env.Library(
+ target= 'logical_clock_test_fixture',
+ source= [
+ 'logical_clock_test_fixture.cpp',
+ ],
+ LIBDEPS= [
+ 'service_context',
+ 'logical_clock',
+ 'signed_logical_time',
+ '$BUILD_DIR/mongo/unittest/unittest',
+ ],
+)
+
+env.Library(
target= 'op_observer_noop',
source= [
'op_observer_noop.cpp',
diff --git a/src/mongo/db/commands/getmore_cmd.cpp b/src/mongo/db/commands/getmore_cmd.cpp
index 0381d462f56..4bedfe06e01 100644
--- a/src/mongo/db/commands/getmore_cmd.cpp
+++ b/src/mongo/db/commands/getmore_cmd.cpp
@@ -43,7 +43,6 @@
#include "mongo/db/curop.h"
#include "mongo/db/db_raii.h"
#include "mongo/db/exec/working_set_common.h"
-#include "mongo/db/global_timestamp.h"
#include "mongo/db/query/cursor_response.h"
#include "mongo/db/query/find.h"
#include "mongo/db/query/find_common.h"
diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp
index 89b4360de91..c89eaa62cb7 100644
--- a/src/mongo/db/db.cpp
+++ b/src/mongo/db/db.cpp
@@ -74,6 +74,7 @@
#include "mongo/db/introspect.h"
#include "mongo/db/json.h"
#include "mongo/db/log_process_details.h"
+#include "mongo/db/logical_clock.h"
#include "mongo/db/mongod_options.h"
#include "mongo/db/op_observer_impl.h"
#include "mongo/db/operation_context.h"
@@ -892,6 +893,10 @@ MONGO_INITIALIZER_WITH_PREREQUISITES(CreateReplicationManager,
topoCoordOptions.maxSyncSourceLagSecs = Seconds(repl::maxSyncSourceLagSecs);
topoCoordOptions.clusterRole = serverGlobalParams.clusterRole;
+ auto timeProofService = stdx::make_unique<TimeProofService>();
+ auto logicalClock =
+ stdx::make_unique<LogicalClock>(serviceContext, std::move(timeProofService), false);
+ LogicalClock::set(serviceContext, std::move(logicalClock));
auto replCoord = stdx::make_unique<repl::ReplicationCoordinatorImpl>(
serviceContext,
getGlobalReplSettings(),
diff --git a/src/mongo/db/global_timestamp.cpp b/src/mongo/db/global_timestamp.cpp
deleted file mode 100644
index 0dbb6c2cf6b..00000000000
--- a/src/mongo/db/global_timestamp.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * Copyright (C) 2014 MongoDB, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the GNU Affero General Public License in all respects for
- * all of the code used other than as permitted herein. If you modify file(s)
- * with this exception, you may extend this exception to your version of the
- * file(s), but you are not obligated to do so. If you do not wish to do so,
- * delete this exception statement from your version. If you delete this
- * exception statement from all source files in the program, then also delete
- * it in the license file.
- */
-
-#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kDefault
-
-#include "mongo/platform/basic.h"
-
-#include "mongo/db/global_timestamp.h"
-#include "mongo/db/service_context.h"
-#include "mongo/platform/atomic_word.h"
-#include "mongo/util/clock_source.h"
-#include "mongo/util/log.h"
-#include "mongo/util/time_support.h"
-
-namespace mongo {
-namespace {
-// This is the value of the next timestamp to handed out.
-AtomicUInt64 globalTimestamp(0);
-} // namespace
-
-void setGlobalTimestamp(ServiceContext* service, const Timestamp& newTime) {
- // TODO: SERVER-27746 replace with LogicalTime
- globalTimestamp.store(newTime.asULL() + 1);
-}
-
-Timestamp getLastSetTimestamp() {
- return Timestamp(globalTimestamp.load() - 1);
-}
-
-Timestamp getNextGlobalTimestamp(ServiceContext* service, unsigned count) {
- // TODO: SERVER-27746 replace with LogicalTime
- const unsigned now = durationCount<Seconds>(
- getGlobalServiceContext()->getFastClockSource()->now().toDurationSinceEpoch());
- invariant(now != 0); // This is a sentinel value for null Timestamps.
- invariant(count != 0);
-
- // Optimistic approach: just increment the timestamp, assuming the seconds still match.
- auto first = globalTimestamp.fetchAndAdd(count);
- auto currentTimestamp = first + count; // What we just set it to.
- unsigned globalSecs = Timestamp(currentTimestamp).getSecs();
-
- // Fail if time is not moving forward for 2**31 calls to getNextGlobalTimestamp.
- if (MONGO_unlikely(globalSecs > now) && Timestamp(currentTimestamp).getInc() >= 1U << 31) {
- mongo::severe() << "clock skew detected, prev: " << globalSecs << " now: " << now;
- fassertFailed(17449);
- }
-
- // If the seconds need to be updated, try to do it. This can happen at most once per second.
- if (MONGO_unlikely(globalSecs < now)) {
- // First fix the seconds portion.
- while (globalSecs < now) {
- const auto desired = Timestamp(now, 1).asULL();
-
- auto actual = globalTimestamp.compareAndSwap(currentTimestamp, desired);
- if (actual == currentTimestamp)
- break; // We successfully set the secs, so we're done here.
-
- // We raced with someone else. Try again, unless they fixed the secs field for us.
- currentTimestamp = actual;
- globalSecs = Timestamp(currentTimestamp).getSecs();
- }
-
- // Now reserve our timestamps with the new value of secs.
- first = globalTimestamp.fetchAndAdd(count);
- }
-
- return Timestamp(first);
-}
-} // namespace mongo
diff --git a/src/mongo/db/logical_clock.cpp b/src/mongo/db/logical_clock.cpp
index ad61792045b..6aeef259528 100644
--- a/src/mongo/db/logical_clock.cpp
+++ b/src/mongo/db/logical_clock.cpp
@@ -26,13 +26,17 @@
* it in the license file.
*/
+#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kDefault
+
+#include "mongo/platform/basic.h"
+
#include "mongo/db/logical_clock.h"
#include "mongo/base/status.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/service_context.h"
#include "mongo/db/time_proof_service.h"
-#include "mongo/platform/basic.h"
+#include "mongo/util/log.h"
namespace mongo {
@@ -85,6 +89,16 @@ Status LogicalClock::advanceClusterTime(const SignedLogicalTime& newTime) {
return Status::OK();
}
+Status LogicalClock::advanceClusterTimeFromTrustedSource(LogicalTime newTime) {
+ stdx::lock_guard<stdx::mutex> lock(_mutex);
+ // TODO: rate check per SERVER-27721
+ if (newTime > _clusterTime.getTime()) {
+ _clusterTime = _makeSignedLogicalTime(newTime);
+ }
+
+ return Status::OK();
+}
+
LogicalTime LogicalClock::reserveTicks(uint64_t ticks) {
invariant(ticks > 0);
@@ -104,6 +118,14 @@ LogicalTime LogicalClock::reserveTicks(uint64_t ticks) {
auto currentTime = clusterTimestamp;
clusterTimestamp.addTicks(ticks - 1);
+ // Fail if time is not moving forward for 2**31 ticks
+ if (MONGO_unlikely(clusterTimestamp.asTimestamp().getSecs() > wallClockSecs) &&
+ clusterTimestamp.asTimestamp().getInc() >= 1U << 31) {
+ mongo::severe() << "clock skew detected, prev: " << wallClockSecs
+ << " now: " << clusterTimestamp.asTimestamp().getSecs();
+ fassertFailed(17449);
+ }
+
_clusterTime = _makeSignedLogicalTime(clusterTimestamp);
return currentTime;
}
diff --git a/src/mongo/db/logical_clock.h b/src/mongo/db/logical_clock.h
index 57d8dc4b80b..ffb78848986 100644
--- a/src/mongo/db/logical_clock.h
+++ b/src/mongo/db/logical_clock.h
@@ -63,7 +63,12 @@ public:
* Returns an error if the newTime does not pass the rate check or proof validation,
* OK otherwise.
*/
- Status advanceClusterTime(const SignedLogicalTime& newTime);
+ Status advanceClusterTime(const SignedLogicalTime&);
+
+ /**
+ * Simliar to advaneClusterTime, but only does rate checking and not proof validation.
+ */
+ Status advanceClusterTimeFromTrustedSource(LogicalTime);
/**
* Returns the current clusterTime.
@@ -74,7 +79,7 @@ public:
* Returns the next clusterTime value and provides the guarantee that the next reserveTicks
* call will return the value at least nTicks ticks in the future from the current clusterTime.
*/
- LogicalTime reserveTicks(uint64_t nTicks = 1);
+ LogicalTime reserveTicks(uint64_t nTicks);
/**
* Resets _clusterTime to the signed time created from newTime. Should be used at the
diff --git a/src/mongo/db/logical_clock_test_fixture.cpp b/src/mongo/db/logical_clock_test_fixture.cpp
new file mode 100644
index 00000000000..64cf8182f22
--- /dev/null
+++ b/src/mongo/db/logical_clock_test_fixture.cpp
@@ -0,0 +1,49 @@
+/**
+ * Copyright (C) 2017 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/db/logical_clock_test_fixture.h"
+
+#include "mongo/db/logical_clock.h"
+#include "mongo/db/service_context.h"
+#include "mongo/db/time_proof_service.h"
+#include "mongo/stdx/memory.h"
+
+namespace mongo {
+
+void LogicalClockTest::setUp() {
+ auto service = getGlobalServiceContext();
+
+ auto timeProofService = stdx::make_unique<TimeProofService>();
+ auto logicalClock =
+ stdx::make_unique<LogicalClock>(service, std::move(timeProofService), false);
+ LogicalClock::set(service, std::move(logicalClock));
+}
+
+} // namespace mongo
diff --git a/src/mongo/db/global_timestamp.h b/src/mongo/db/logical_clock_test_fixture.h
index 408d38a6aae..e304e3a5611 100644
--- a/src/mongo/db/global_timestamp.h
+++ b/src/mongo/db/logical_clock_test_fixture.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2014 MongoDB, Inc.
+ * Copyright (C) 2017 MongoDB Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
@@ -28,21 +28,22 @@
#pragma once
-#include "mongo/bson/timestamp.h"
+#include "mongo/unittest/unittest.h"
namespace mongo {
-class ServiceContext;
-
-void setGlobalTimestamp(ServiceContext* service, const Timestamp& newTime);
-
/**
- * Returns the value of the global Timestamp generated last time or set.
+ * A test fixture that installs a LogicalClock instance onto a service context.
*/
-Timestamp getLastSetTimestamp();
+class LogicalClockTest : public unittest::Test {
+public:
+ ~LogicalClockTest() override = default;
-/**
- * Generates a new and unique Timestamp.
- * If count > 1 that many unique Timestamps are reserved starting with the returned value.
- */
-Timestamp getNextGlobalTimestamp(ServiceContext* service, unsigned count = 1);
-}
+protected:
+ /**
+ * Sets up this fixture with a context and a LogicalClock.
+ */
+ void setUp() override;
+ void tearDown() override{};
+};
+
+} // namespace mongo
diff --git a/src/mongo/db/logical_time_test.cpp b/src/mongo/db/logical_time_test.cpp
index d5d1f15a7b2..e7d7d8e2819 100644
--- a/src/mongo/db/logical_time_test.cpp
+++ b/src/mongo/db/logical_time_test.cpp
@@ -80,7 +80,7 @@ TEST(LogicalTime, addTicksConst) {
Timestamp tY(2);
const auto lT = LogicalTime(tX);
- auto lQ = lT.addTicks(1);
+ const auto lQ = lT.addTicks(1);
ASSERT_TRUE(tX == lT.asTimestamp());
ASSERT_TRUE(tY == lQ.asTimestamp());
diff --git a/src/mongo/db/ops/SConscript b/src/mongo/db/ops/SConscript
index 9d833d2b06b..7b5ddd1f629 100644
--- a/src/mongo/db/ops/SConscript
+++ b/src/mongo/db/ops/SConscript
@@ -71,9 +71,11 @@ env.Library(
],
LIBDEPS=[
'$BUILD_DIR/mongo/base',
+ '$BUILD_DIR/mongo/db/service_context',
+ '$BUILD_DIR/mongo/db/logical_clock',
+ '$BUILD_DIR/mongo/db/logical_time',
'$BUILD_DIR/mongo/db/bson/dotted_path_support',
'$BUILD_DIR/mongo/db/matcher/expressions',
- '$BUILD_DIR/mongo/db/global_timestamp',
'update_common',
],
)
@@ -111,6 +113,7 @@ env.CppUnitTest(
LIBDEPS=[
'$BUILD_DIR/mongo/bson/mutable/mutable_bson_test_utils',
'$BUILD_DIR/mongo/db/service_context_noop_init',
+ '$BUILD_DIR/mongo/db/logical_clock_test_fixture',
'update',
],
)
@@ -130,6 +133,7 @@ env.CppUnitTest(
LIBDEPS=[
'$BUILD_DIR/mongo/bson/mutable/mutable_bson_test_utils',
'$BUILD_DIR/mongo/db/service_context_noop_init',
+ '$BUILD_DIR/mongo/db/logical_clock_test_fixture',
'update',
],
)
diff --git a/src/mongo/db/ops/insert.cpp b/src/mongo/db/ops/insert.cpp
index 3cddceac1d5..1928ceb3661 100644
--- a/src/mongo/db/ops/insert.cpp
+++ b/src/mongo/db/ops/insert.cpp
@@ -29,7 +29,8 @@
*/
#include "mongo/db/ops/insert.h"
-#include "mongo/db/global_timestamp.h"
+#include "mongo/db/logical_clock.h"
+#include "mongo/db/logical_time.h"
#include "mongo/db/views/durable_view_catalog.h"
#include "mongo/util/mongoutils/str.h"
@@ -124,7 +125,8 @@ StatusWith<BSONObj> fixDocumentForInsert(ServiceContext* service, const BSONObj&
if (hadId && e.fieldNameStringData() == "_id") {
// no-op
} else if (e.type() == bsonTimestamp && e.timestampValue() == 0) {
- b.append(e.fieldName(), getNextGlobalTimestamp(service));
+ auto nextTime = LogicalClock::get(service)->reserveTicks(1);
+ b.append(e.fieldName(), nextTime.asTimestamp());
} else {
b.append(e);
}
diff --git a/src/mongo/db/ops/modifier_current_date.cpp b/src/mongo/db/ops/modifier_current_date.cpp
index f693292781d..78dc3c57d4f 100644
--- a/src/mongo/db/ops/modifier_current_date.cpp
+++ b/src/mongo/db/ops/modifier_current_date.cpp
@@ -26,11 +26,14 @@
* it in the license file.
*/
+#include "mongo/platform/basic.h"
+
#include "mongo/db/ops/modifier_current_date.h"
#include "mongo/base/error_codes.h"
#include "mongo/bson/mutable/document.h"
-#include "mongo/db/global_timestamp.h"
+#include "mongo/db/logical_clock.h"
+#include "mongo/db/logical_time.h"
#include "mongo/db/ops/field_checker.h"
#include "mongo/db/ops/log_builder.h"
#include "mongo/db/ops/path_support.h"
@@ -226,7 +229,8 @@ Status ModifierCurrentDate::apply() const {
return s;
} else {
ServiceContext* service = getGlobalServiceContext();
- Status s = elemToSet.setValueTimestamp(getNextGlobalTimestamp(service));
+ auto ts = LogicalClock::get(service)->reserveTicks(1).asTimestamp();
+ Status s = elemToSet.setValueTimestamp(ts);
if (!s.isOK())
return s;
}
diff --git a/src/mongo/db/ops/modifier_current_date_test.cpp b/src/mongo/db/ops/modifier_current_date_test.cpp
index 81bcd4d04e0..a9f0865c8be 100644
--- a/src/mongo/db/ops/modifier_current_date_test.cpp
+++ b/src/mongo/db/ops/modifier_current_date_test.cpp
@@ -35,6 +35,7 @@
#include "mongo/bson/mutable/mutable_bson_test_utils.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/json.h"
+#include "mongo/db/logical_clock_test_fixture.h"
#include "mongo/db/ops/log_builder.h"
#include "mongo/unittest/unittest.h"
@@ -52,6 +53,12 @@ using mongo::mutablebson::ConstElement;
using mongo::mutablebson::Document;
using mongo::mutablebson::Element;
+using Init = mongo::LogicalClockTest;
+using BoolInput = mongo::LogicalClockTest;
+using DateInput = mongo::LogicalClockTest;
+using TimestampInput = mongo::LogicalClockTest;
+using DottedTimestampInput = mongo::LogicalClockTest;
+
/**
* Helper to validate oplog entries in the tests below.
*/
@@ -99,7 +106,7 @@ private:
ModifierCurrentDate _mod;
};
-TEST(Init, ValidValues) {
+TEST_F(Init, ValidValues) {
BSONObj modObj;
ModifierCurrentDate mod;
@@ -116,7 +123,7 @@ TEST(Init, ValidValues) {
ModifierInterface::Options::normal()));
}
-TEST(Init, FailToInitWithInvalidValue) {
+TEST_F(Init, FailToInitWithInvalidValue) {
BSONObj modObj;
ModifierCurrentDate mod;
@@ -166,7 +173,7 @@ TEST(Init, FailToInitWithInvalidValue) {
ModifierInterface::Options::normal()));
}
-TEST(BoolInput, EmptyStartDoc) {
+TEST_F(BoolInput, EmptyStartDoc) {
Document doc(fromjson("{ }"));
Mod mod(fromjson("{ $currentDate : { a : true } }"));
@@ -187,7 +194,7 @@ TEST(BoolInput, EmptyStartDoc) {
validateOplogEntry(oplogFormat, logDoc);
}
-TEST(DateInput, EmptyStartDoc) {
+TEST_F(DateInput, EmptyStartDoc) {
Document doc(fromjson("{ }"));
Mod mod(fromjson("{ $currentDate : { a : {$type: 'date' } } }"));
@@ -208,7 +215,7 @@ TEST(DateInput, EmptyStartDoc) {
validateOplogEntry(oplogFormat, logDoc);
}
-TEST(TimestampInput, EmptyStartDoc) {
+TEST_F(TimestampInput, EmptyStartDoc) {
Document doc(fromjson("{ }"));
Mod mod(fromjson("{ $currentDate : { a : {$type : 'timestamp' } } }"));
@@ -230,7 +237,7 @@ TEST(TimestampInput, EmptyStartDoc) {
validateOplogEntry(oplogFormat, logDoc);
}
-TEST(BoolInput, ExistingStringDoc) {
+TEST_F(BoolInput, ExistingStringDoc) {
Document doc(fromjson("{ a: 'a' }"));
Mod mod(fromjson("{ $currentDate : { a : true } }"));
@@ -251,7 +258,7 @@ TEST(BoolInput, ExistingStringDoc) {
validateOplogEntry(oplogFormat, logDoc);
}
-TEST(BoolInput, ExistingDateDoc) {
+TEST_F(BoolInput, ExistingDateDoc) {
Document doc(fromjson("{ a: {$date: 0 } }"));
Mod mod(fromjson("{ $currentDate : { a : true } }"));
@@ -272,7 +279,7 @@ TEST(BoolInput, ExistingDateDoc) {
validateOplogEntry(oplogFormat, logDoc);
}
-TEST(DateInput, ExistingDateDoc) {
+TEST_F(DateInput, ExistingDateDoc) {
Document doc(fromjson("{ a: {$date: 0 } }"));
Mod mod(fromjson("{ $currentDate : { a : {$type: 'date' } } }"));
@@ -293,7 +300,7 @@ TEST(DateInput, ExistingDateDoc) {
validateOplogEntry(oplogFormat, logDoc);
}
-TEST(TimestampInput, ExistingDateDoc) {
+TEST_F(TimestampInput, ExistingDateDoc) {
Document doc(fromjson("{ a: {$date: 0 } }"));
Mod mod(fromjson("{ $currentDate : { a : {$type : 'timestamp' } } }"));
@@ -315,7 +322,7 @@ TEST(TimestampInput, ExistingDateDoc) {
validateOplogEntry(oplogFormat, logDoc);
}
-TEST(TimestampInput, ExistingEmbeddedDateDoc) {
+TEST_F(TimestampInput, ExistingEmbeddedDateDoc) {
Document doc(fromjson("{ a: {b: {$date: 0 } } }"));
Mod mod(fromjson("{ $currentDate : { 'a.b' : {$type : 'timestamp' } } }"));
@@ -337,7 +344,7 @@ TEST(TimestampInput, ExistingEmbeddedDateDoc) {
validateOplogEntry(oplogFormat, logDoc);
}
-TEST(DottedTimestampInput, EmptyStartDoc) {
+TEST_F(DottedTimestampInput, EmptyStartDoc) {
Document doc(fromjson("{ }"));
Mod mod(fromjson("{ $currentDate : { 'a.b' : {$type : 'timestamp' } } }"));
diff --git a/src/mongo/db/ops/modifier_object_replace.cpp b/src/mongo/db/ops/modifier_object_replace.cpp
index 4dd1565dbdb..e74617ea7ef 100644
--- a/src/mongo/db/ops/modifier_object_replace.cpp
+++ b/src/mongo/db/ops/modifier_object_replace.cpp
@@ -31,7 +31,8 @@
#include "mongo/base/data_view.h"
#include "mongo/base/error_codes.h"
#include "mongo/bson/mutable/document.h"
-#include "mongo/db/global_timestamp.h"
+#include "mongo/db/logical_clock.h"
+#include "mongo/db/logical_time.h"
#include "mongo/db/ops/log_builder.h"
#include "mongo/db/service_context.h"
#include "mongo/util/mongoutils/str.h"
@@ -57,7 +58,7 @@ Status fixupTimestamps(const BSONObj& obj) {
if (timestamp == 0) {
// performance note, this locks a mutex:
ServiceContext* service = getGlobalServiceContext();
- Timestamp ts(getNextGlobalTimestamp(service));
+ auto ts = LogicalClock::get(service)->reserveTicks(1).asTimestamp();
timestampView.write(tagLittleEndian(ts.asULL()));
}
}
diff --git a/src/mongo/db/ops/modifier_object_replace_test.cpp b/src/mongo/db/ops/modifier_object_replace_test.cpp
index 4f55fe2cbf4..c661246e7f5 100644
--- a/src/mongo/db/ops/modifier_object_replace_test.cpp
+++ b/src/mongo/db/ops/modifier_object_replace_test.cpp
@@ -39,6 +39,7 @@
#include "mongo/bson/timestamp.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/json.h"
+#include "mongo/db/logical_clock_test_fixture.h"
#include "mongo/db/ops/log_builder.h"
#include "mongo/unittest/unittest.h"
@@ -58,6 +59,11 @@ using mongo::NumberInt;
using mongo::Status;
using mongo::StringData;
+using Normal = mongo::LogicalClockTest;
+using IdLeft = mongo::LogicalClockTest;
+using IdImmutable = mongo::LogicalClockTest;
+using Timestamp = mongo::LogicalClockTest;
+
/** Helper to build and manipulate a $set mod. */
class Mod {
public:
@@ -94,7 +100,7 @@ private:
};
// Normal replacements below
-TEST(Normal, SingleFieldDoc) {
+TEST_F(Normal, SingleFieldDoc) {
Document doc(fromjson("{_id:1, a:1}"));
Mod mod(fromjson("{_id:1, b:12}"));
@@ -111,7 +117,7 @@ TEST(Normal, SingleFieldDoc) {
ASSERT_EQUALS(doc, logDoc);
}
-TEST(Normal, ComplexDoc) {
+TEST_F(Normal, ComplexDoc) {
Document doc(fromjson("{_id:1, a:1}"));
Mod mod(fromjson("{_id:1, b:[123], c: {r:true}}"));
@@ -128,7 +134,7 @@ TEST(Normal, ComplexDoc) {
ASSERT_EQUALS(doc, logDoc);
}
-TEST(Normal, OnlyIdField) {
+TEST_F(Normal, OnlyIdField) {
Document doc(fromjson("{}"));
Mod mod(fromjson("{_id:1}"));
@@ -147,7 +153,7 @@ TEST(Normal, OnlyIdField) {
// These updates have to do with updates without an _id field
// (the existing _id isn't removed)
-TEST(IdLeft, EmptyDocReplacement) {
+TEST_F(IdLeft, EmptyDocReplacement) {
Document doc(fromjson("{_id:1}"));
Mod mod(fromjson("{}"));
@@ -164,7 +170,7 @@ TEST(IdLeft, EmptyDocReplacement) {
ASSERT_EQUALS(doc, logDoc);
}
-TEST(IdLeft, EmptyDoc) {
+TEST_F(IdLeft, EmptyDoc) {
Document doc(fromjson("{_id:1}"));
Mod mod(fromjson("{}"));
@@ -181,7 +187,7 @@ TEST(IdLeft, EmptyDoc) {
ASSERT_EQUALS(doc, logDoc);
}
-TEST(IdLeft, SingleFieldAddition) {
+TEST_F(IdLeft, SingleFieldAddition) {
Document doc(fromjson("{_id:1}"));
Mod mod(fromjson("{a:1}"));
@@ -198,7 +204,7 @@ TEST(IdLeft, SingleFieldAddition) {
ASSERT_EQUALS(doc, logDoc);
}
-TEST(IdLeft, SingleFieldReplaced) {
+TEST_F(IdLeft, SingleFieldReplaced) {
Document doc(fromjson("{a: []}"));
Mod mod(fromjson("{a:10}"));
@@ -215,7 +221,7 @@ TEST(IdLeft, SingleFieldReplaced) {
ASSERT_EQUALS(doc, logDoc);
}
-TEST(IdLeft, SwapFields) {
+TEST_F(IdLeft, SwapFields) {
Document doc(fromjson("{_id:1, a:1}"));
Mod mod(fromjson("{b:1}"));
@@ -232,7 +238,7 @@ TEST(IdLeft, SwapFields) {
ASSERT_EQUALS(doc, logDoc);
}
-TEST(IdImmutable, ReplaceIdNumber) {
+TEST_F(IdImmutable, ReplaceIdNumber) {
Document doc(fromjson("{_id:1, a:1}"));
Mod mod(fromjson("{_id:2}"));
@@ -242,7 +248,7 @@ TEST(IdImmutable, ReplaceIdNumber) {
ASSERT_NOT_OK(mod.apply());
}
-TEST(IdImmutable, ReplaceIdNumberSameVal) {
+TEST_F(IdImmutable, ReplaceIdNumberSameVal) {
Document doc(fromjson("{_id:1, a:1}"));
Mod mod(fromjson("{_id:2}"));
@@ -252,7 +258,7 @@ TEST(IdImmutable, ReplaceIdNumberSameVal) {
ASSERT_NOT_OK(mod.apply());
}
-TEST(IdImmutable, ReplaceEmbeddedId) {
+TEST_F(IdImmutable, ReplaceEmbeddedId) {
Document doc(fromjson("{_id:{a:1, b:2}, a:1}"));
Mod mod(fromjson("{_id:{b:2, a:1}}"));
@@ -262,7 +268,7 @@ TEST(IdImmutable, ReplaceEmbeddedId) {
ASSERT_NOT_OK(mod.apply());
}
-TEST(Timestamp, IdNotReplaced) {
+TEST_F(Timestamp, IdNotReplaced) {
Document doc(fromjson("{}"));
Mod mod(fromjson("{_id:Timestamp(0,0), a:1}"));
@@ -283,7 +289,7 @@ TEST(Timestamp, IdNotReplaced) {
ASSERT(idElem.getValueTimestamp().isNull());
}
-TEST(Timestamp, ReplaceAll) {
+TEST_F(Timestamp, ReplaceAll) {
Document doc(fromjson("{}"));
Mod mod(fromjson("{a:Timestamp(0,0), r:1, x:1, b:Timestamp(0,0)}"));
diff --git a/src/mongo/db/repl/SConscript b/src/mongo/db/repl/SConscript
index 1736bcc2c0c..dd7233cd6b3 100644
--- a/src/mongo/db/repl/SConscript
+++ b/src/mongo/db/repl/SConscript
@@ -424,7 +424,6 @@ env.Library('repl_coordinator_impl',
],
LIBDEPS=[
'$BUILD_DIR/mongo/db/common',
- '$BUILD_DIR/mongo/db/global_timestamp',
'$BUILD_DIR/mongo/db/index/index_descriptor',
'$BUILD_DIR/mongo/db/server_options_core',
'$BUILD_DIR/mongo/db/service_context',
@@ -1166,6 +1165,8 @@ env.Library(
'$BUILD_DIR/mongo/client/clientdriver',
'$BUILD_DIR/mongo/db/auth/authcore',
'$BUILD_DIR/mongo/db/commands',
+ '$BUILD_DIR/mongo/db/logical_clock',
+ '$BUILD_DIR/mongo/db/logical_time',
'$BUILD_DIR/mongo/db/commands/list_collections_filter',
'$BUILD_DIR/mongo/rpc/client_metadata',
'$BUILD_DIR/mongo/db/concurrency/lock_manager',
diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp
index 0e9b8c0366c..82c285441b6 100644
--- a/src/mongo/db/repl/oplog.cpp
+++ b/src/mongo/db/repl/oplog.cpp
@@ -62,11 +62,12 @@
#include "mongo/db/db_raii.h"
#include "mongo/db/dbdirectclient.h"
#include "mongo/db/dbhelpers.h"
-#include "mongo/db/global_timestamp.h"
#include "mongo/db/index/index_access_method.h"
#include "mongo/db/index/index_descriptor.h"
#include "mongo/db/index_builder.h"
#include "mongo/db/keypattern.h"
+#include "mongo/db/logical_clock.h"
+#include "mongo/db/logical_time.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/op_observer.h"
#include "mongo/db/ops/delete.h"
@@ -161,7 +162,8 @@ void getNextOpTime(OperationContext* txn,
}
stdx::lock_guard<stdx::mutex> lk(newOpMutex);
- Timestamp ts = getNextGlobalTimestamp(txn->getServiceContext(), count);
+
+ auto ts = LogicalClock::get(txn)->reserveTicks(count).asTimestamp();
newTimestampNotifier.notify_all();
fassert(28560, oplog->getRecordStore()->oplogDiskLocRegister(txn, ts));
@@ -1109,7 +1111,7 @@ Status applyCommand_inlock(OperationContext* txn,
void setNewTimestamp(ServiceContext* service, const Timestamp& newTime) {
stdx::lock_guard<stdx::mutex> lk(newOpMutex);
- setGlobalTimestamp(service, newTime);
+ LogicalClock::get(service)->advanceClusterTimeFromTrustedSource(LogicalTime(newTime));
newTimestampNotifier.notify_all();
}
@@ -1193,9 +1195,10 @@ void SnapshotThread::run() {
if (_inShutdown.load())
return;
- if (_forcedSnapshotPending.load() || lastTimestamp != getLastSetTimestamp()) {
+ auto clusterTime = LogicalClock::get(service)->getClusterTime().getTime();
+ if (_forcedSnapshotPending.load() || lastTimestamp != clusterTime.asTimestamp()) {
_forcedSnapshotPending.store(false);
- lastTimestamp = getLastSetTimestamp();
+ lastTimestamp = clusterTime.asTimestamp();
break;
}
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp
index 623f5251977..099f9462504 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl.cpp
@@ -40,8 +40,9 @@
#include "mongo/db/client.h"
#include "mongo/db/commands.h"
#include "mongo/db/concurrency/d_concurrency.h"
-#include "mongo/db/global_timestamp.h"
#include "mongo/db/index/index_descriptor.h"
+#include "mongo/db/logical_clock.h"
+#include "mongo/db/logical_time.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"
@@ -2677,7 +2678,9 @@ void ReplicationCoordinatorImpl::_performPostMemberStateUpdateAction(
} else {
_electionId = OID::gen();
}
- _topCoord->processWinElection(_electionId, getNextGlobalTimestamp(getServiceContext()));
+
+ auto ts = LogicalClock::get(getServiceContext())->reserveTicks(1).asTimestamp();
+ _topCoord->processWinElection(_electionId, ts);
invariant(!_isCatchingUp);
invariant(!_isWaitingForDrainToComplete);
_isCatchingUp = true;
@@ -2872,13 +2875,15 @@ ReplicationCoordinatorImpl::_setCurrentRSConfig_inlock(const ReplicaSetConfig& n
// Downgrade
invariant(newConfig.getProtocolVersion() == 0);
_electionId = OID::gen();
- _topCoord->setElectionInfo(_electionId, getNextGlobalTimestamp(getServiceContext()));
+ auto ts = LogicalClock::get(getServiceContext())->reserveTicks(1).asTimestamp();
+ _topCoord->setElectionInfo(_electionId, ts);
} else if (oldConfig.getProtocolVersion() < newConfig.getProtocolVersion()) {
// Upgrade
invariant(newConfig.getProtocolVersion() == 1);
invariant(_topCoord->getTerm() != OpTime::kUninitializedTerm);
_electionId = OID::fromTerm(_topCoord->getTerm());
- _topCoord->setElectionInfo(_electionId, getNextGlobalTimestamp(getServiceContext()));
+ auto ts = LogicalClock::get(getServiceContext())->reserveTicks(1).asTimestamp();
+ _topCoord->setElectionInfo(_electionId, ts);
}
}
diff --git a/src/mongo/db/repl/replication_coordinator_test_fixture.cpp b/src/mongo/db/repl/replication_coordinator_test_fixture.cpp
index 61fd52855de..c0bbda407f1 100644
--- a/src/mongo/db/repl/replication_coordinator_test_fixture.cpp
+++ b/src/mongo/db/repl/replication_coordinator_test_fixture.cpp
@@ -32,6 +32,7 @@
#include "mongo/db/repl/replication_coordinator_test_fixture.h"
+#include "mongo/db/logical_clock.h"
#include "mongo/db/operation_context_noop.h"
#include "mongo/db/repl/is_master_response.h"
#include "mongo/db/repl/repl_set_heartbeat_args.h"
@@ -41,6 +42,7 @@
#include "mongo/db/repl/replication_coordinator_impl.h"
#include "mongo/db/repl/storage_interface_mock.h"
#include "mongo/db/repl/topology_coordinator_impl.h"
+#include "mongo/db/time_proof_service.h"
#include "mongo/executor/network_interface_mock.h"
#include "mongo/stdx/functional.h"
#include "mongo/stdx/memory.h"
@@ -120,6 +122,11 @@ void ReplCoordTest::init() {
// PRNG seed for tests.
const int64_t seed = 0;
+ auto timeProofService = stdx::make_unique<TimeProofService>();
+ auto logicalClock =
+ stdx::make_unique<LogicalClock>(service, std::move(timeProofService), false);
+ LogicalClock::set(service, std::move(logicalClock));
+
TopologyCoordinatorImpl::Options settings;
auto topo = stdx::make_unique<TopologyCoordinatorImpl>(settings);
_topo = topo.get();
diff --git a/src/mongo/db/repl/sync_tail.cpp b/src/mongo/db/repl/sync_tail.cpp
index a0302e3addb..8f752b49e05 100644
--- a/src/mongo/db/repl/sync_tail.cpp
+++ b/src/mongo/db/repl/sync_tail.cpp
@@ -52,7 +52,6 @@
#include "mongo/db/curop.h"
#include "mongo/db/db_raii.h"
#include "mongo/db/dbhelpers.h"
-#include "mongo/db/global_timestamp.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/prefetch.h"
#include "mongo/db/query/query_knobs.h"
diff --git a/src/mongo/db/s/balancer/migration_manager_test.cpp b/src/mongo/db/s/balancer/migration_manager_test.cpp
index 2f2012b1ee9..a037f434ebc 100644
--- a/src/mongo/db/s/balancer/migration_manager_test.cpp
+++ b/src/mongo/db/s/balancer/migration_manager_test.cpp
@@ -43,6 +43,7 @@
#include "mongo/s/config_server_test_fixture.h"
#include "mongo/s/move_chunk_request.h"
#include "mongo/stdx/memory.h"
+#include "mongo/util/scopeguard.h"
namespace mongo {
namespace {
@@ -311,6 +312,7 @@ TEST_F(MigrationManagerTest, OneCollectionTwoMigrations) {
const std::vector<MigrateInfo> migrationRequests{{kShardId1, chunk1}, {kShardId3, chunk2}};
auto future = launchAsync([this, migrationRequests] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready("Test");
auto txn = cc().makeOperationContext();
@@ -373,6 +375,7 @@ TEST_F(MigrationManagerTest, TwoCollectionsTwoMigrationsEach) {
{kShardId3, chunk2coll2}};
auto future = launchAsync([this, migrationRequests] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready("Test");
auto txn = cc().makeOperationContext();
@@ -427,6 +430,7 @@ TEST_F(MigrationManagerTest, SourceShardNotFound) {
const std::vector<MigrateInfo> migrationRequests{{kShardId1, chunk1}, {kShardId3, chunk2}};
auto future = launchAsync([this, chunk1, chunk2, migrationRequests] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready("Test");
auto txn = cc().makeOperationContext();
@@ -473,6 +477,7 @@ TEST_F(MigrationManagerTest, JumboChunkResponseBackwardsCompatibility) {
const std::vector<MigrateInfo> migrationRequests{{kShardId1, chunk1}};
auto future = launchAsync([this, chunk1, migrationRequests] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready("Test");
auto txn = cc().makeOperationContext();
@@ -511,6 +516,7 @@ TEST_F(MigrationManagerTest, InterruptMigration) {
setUpChunk(collName, kKeyPattern.globalMin(), kKeyPattern.globalMax(), kShardId0, version);
auto future = launchAsync([&] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready("Test");
auto txn = cc().makeOperationContext();
@@ -598,6 +604,7 @@ TEST_F(MigrationManagerTest, RestartMigrationManager) {
_migrationManager->finishRecovery(operationContext(), 0, kDefaultSecondaryThrottle);
auto future = launchAsync([&] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready("Test");
auto txn = cc().makeOperationContext();
@@ -652,6 +659,7 @@ TEST_F(MigrationManagerTest, MigrationRecovery) {
_migrationManager->startRecoveryAndAcquireDistLocks(operationContext());
auto future = launchAsync([this] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready("Test");
auto txn = cc().makeOperationContext();
@@ -753,6 +761,7 @@ TEST_F(MigrationManagerTest, RemoteCallErrorConversionToOperationFailed) {
setUpChunk(collName, BSON(kPattern << 49), kKeyPattern.globalMax(), kShardId2, version);
auto future = launchAsync([&] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready("Test");
auto txn = cc().makeOperationContext();
diff --git a/src/mongo/dbtests/SConscript b/src/mongo/dbtests/SConscript
index 27bb7cfea70..37238d35d0b 100644
--- a/src/mongo/dbtests/SConscript
+++ b/src/mongo/dbtests/SConscript
@@ -123,6 +123,7 @@ dbtest = env.Program(
"$BUILD_DIR/mongo/db/repl/repl_coordinator_global",
"$BUILD_DIR/mongo/db/repl/replmocks",
"$BUILD_DIR/mongo/db/serveronly",
+ "$BUILD_DIR/mongo/db/logical_clock",
"$BUILD_DIR/mongo/db/storage/paths",
"$BUILD_DIR/mongo/util/concurrency/rwlock",
"$BUILD_DIR/mongo/util/net/network",
diff --git a/src/mongo/dbtests/dbtests.cpp b/src/mongo/dbtests/dbtests.cpp
index 4ce21b9097c..52f5f2a4888 100644
--- a/src/mongo/dbtests/dbtests.cpp
+++ b/src/mongo/dbtests/dbtests.cpp
@@ -42,11 +42,13 @@
#include "mongo/db/commands.h"
#include "mongo/db/db_raii.h"
#include "mongo/db/index/index_descriptor.h"
+#include "mongo/db/logical_clock.h"
#include "mongo/db/repl/replication_coordinator_global.h"
#include "mongo/db/repl/replication_coordinator_mock.h"
#include "mongo/db/server_options.h"
#include "mongo/db/service_context.h"
#include "mongo/db/service_context_d.h"
+#include "mongo/db/time_proof_service.h"
#include "mongo/db/wire_version.h"
#include "mongo/dbtests/framework.h"
#include "mongo/scripting/engine.h"
@@ -131,6 +133,12 @@ int dbtestsMain(int argc, char** argv, char** envp) {
repl::ReplSettings replSettings;
replSettings.setOplogSizeBytes(10 * 1024 * 1024);
ServiceContext* service = getGlobalServiceContext();
+
+ auto timeProofService = stdx::make_unique<TimeProofService>();
+ auto logicalClock =
+ stdx::make_unique<LogicalClock>(service, std::move(timeProofService), false);
+ LogicalClock::set(service, std::move(logicalClock));
+
repl::setGlobalReplicationCoordinator(
new repl::ReplicationCoordinatorMock(service, replSettings));
repl::getGlobalReplicationCoordinator()->setFollowerMode(repl::MemberState::RS_PRIMARY);
diff --git a/src/mongo/dbtests/querytests.cpp b/src/mongo/dbtests/querytests.cpp
index 1ca8cf49bf0..5288038b1f8 100644
--- a/src/mongo/dbtests/querytests.cpp
+++ b/src/mongo/dbtests/querytests.cpp
@@ -39,10 +39,11 @@
#include "mongo/db/db_raii.h"
#include "mongo/db/dbdirectclient.h"
#include "mongo/db/dbhelpers.h"
-#include "mongo/db/global_timestamp.h"
#include "mongo/db/index/index_descriptor.h"
#include "mongo/db/json.h"
#include "mongo/db/lasterror.h"
+#include "mongo/db/logical_clock.h"
+#include "mongo/db/logical_time.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/query/find.h"
#include "mongo/db/service_context.h"
@@ -670,12 +671,12 @@ public:
<< 8192),
info);
- Date_t one =
- Date_t::fromMillisSinceEpoch(getNextGlobalTimestamp(_txn.getServiceContext()).asLL());
- Date_t two =
- Date_t::fromMillisSinceEpoch(getNextGlobalTimestamp(_txn.getServiceContext()).asLL());
- Date_t three =
- Date_t::fromMillisSinceEpoch(getNextGlobalTimestamp(_txn.getServiceContext()).asLL());
+ Date_t one = Date_t::fromMillisSinceEpoch(
+ LogicalClock::get(&_txn)->reserveTicks(1).asTimestamp().asLL());
+ Date_t two = Date_t::fromMillisSinceEpoch(
+ LogicalClock::get(&_txn)->reserveTicks(1).asTimestamp().asLL());
+ Date_t three = Date_t::fromMillisSinceEpoch(
+ LogicalClock::get(&_txn)->reserveTicks(1).asTimestamp().asLL());
insert(ns, BSON("ts" << one));
insert(ns, BSON("ts" << two));
insert(ns, BSON("ts" << three));
diff --git a/src/mongo/s/server.cpp b/src/mongo/s/server.cpp
index 68afcfd378b..1a5d0b28ea9 100644
--- a/src/mongo/s/server.cpp
+++ b/src/mongo/s/server.cpp
@@ -54,6 +54,8 @@
#include "mongo/db/initialize_server_global_state.h"
#include "mongo/db/lasterror.h"
#include "mongo/db/log_process_details.h"
+#include "mongo/db/logical_clock.h"
+#include "mongo/db/operation_context.h"
#include "mongo/db/server_options.h"
#include "mongo/db/service_context.h"
#include "mongo/db/service_context_noop.h"
@@ -266,6 +268,11 @@ static ExitCode runMongosServer() {
auto opCtx = cc().makeOperationContext();
+ auto timeProofService = stdx::make_unique<TimeProofService>();
+ auto logicalClock = stdx::make_unique<LogicalClock>(
+ opCtx->getServiceContext(), std::move(timeProofService), false);
+ LogicalClock::set(opCtx->getServiceContext(), std::move(logicalClock));
+
{
Status status = initializeSharding(opCtx.get());
if (!status.isOK()) {
diff --git a/src/mongo/s/sharding_mongod_test_fixture.cpp b/src/mongo/s/sharding_mongod_test_fixture.cpp
index 79097d4682f..d4b3d4d9e2a 100644
--- a/src/mongo/s/sharding_mongod_test_fixture.cpp
+++ b/src/mongo/s/sharding_mongod_test_fixture.cpp
@@ -39,6 +39,7 @@
#include "mongo/db/client.h"
#include "mongo/db/commands.h"
#include "mongo/db/db_raii.h"
+#include "mongo/db/logical_clock.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/op_observer_impl.h"
#include "mongo/db/query/cursor_response.h"
@@ -49,6 +50,7 @@
#include "mongo/db/repl/replication_coordinator.h"
#include "mongo/db/repl/replication_coordinator_mock.h"
#include "mongo/db/service_context_noop.h"
+#include "mongo/db/time_proof_service.h"
#include "mongo/executor/network_interface_mock.h"
#include "mongo/executor/task_executor_pool.h"
#include "mongo/executor/thread_pool_task_executor_test_fixture.h"
@@ -107,6 +109,11 @@ void ShardingMongodTestFixture::setUp() {
// Set up this node as part of a replica set.
+ auto timeProofService = stdx::make_unique<TimeProofService>();
+ auto logicalClock =
+ stdx::make_unique<LogicalClock>(service, std::move(timeProofService), false);
+ LogicalClock::set(service, std::move(logicalClock));
+
repl::ReplSettings replSettings;
replSettings.setReplSetString(ConnectionString::forReplicaSet(_setName, _servers).toString());
auto replCoordPtr = makeReplicationCoordinator(replSettings);