From 686ee776666ebcfa15f3744142f74b6f1d59e617 Mon Sep 17 00:00:00 2001 From: Kevin Pulo Date: Tue, 15 Sep 2020 11:44:54 +1000 Subject: SERVER-48433 Remove LogicalClock facade --- src/mongo/db/SConscript | 9 +- src/mongo/db/auth/auth_op_observer_test.cpp | 1 - src/mongo/db/catalog/index_build_block.cpp | 4 +- src/mongo/db/catalog/index_catalog_entry_impl.cpp | 1 - src/mongo/db/catalog/index_catalog_impl.cpp | 4 +- src/mongo/db/commands/dbhash.cpp | 1 - src/mongo/db/commands/drop_indexes.cpp | 4 +- src/mongo/db/commands/snapshot_management.cpp | 4 +- src/mongo/db/key_generator.cpp | 16 +- src/mongo/db/keys_collection_client_direct.cpp | 1 - src/mongo/db/keys_collection_manager.cpp | 6 +- .../db/keys_collection_manager_sharding_test.cpp | 2 +- src/mongo/db/logical_clock.cpp | 82 ----- src/mongo/db/logical_clock.h | 74 ----- src/mongo/db/logical_clock_test.cpp | 336 --------------------- src/mongo/db/logical_clock_test_fixture.cpp | 105 ------- src/mongo/db/logical_clock_test_fixture.h | 81 ----- src/mongo/db/logical_time_validator.cpp | 6 +- src/mongo/db/mongod_main.cpp | 4 - src/mongo/db/op_msg_fuzzer.cpp | 3 - src/mongo/db/op_observer_impl_test.cpp | 1 - .../db/pipeline/document_source_change_stream.cpp | 7 +- .../document_source_change_stream_transform.cpp | 1 - src/mongo/db/pipeline/expression_context_test.cpp | 3 - src/mongo/db/pipeline/sharded_agg_helpers.cpp | 5 +- src/mongo/db/pipeline/variables.cpp | 10 +- src/mongo/db/read_concern_mongod.cpp | 10 +- src/mongo/db/read_write_concern_defaults.cpp | 5 +- src/mongo/db/read_write_concern_defaults_test.cpp | 5 +- src/mongo/db/repair.cpp | 4 +- src/mongo/db/repl/oplog_fetcher_test.cpp | 15 +- ...replication_coordinator_external_state_impl.cpp | 5 +- .../repl/replication_coordinator_test_fixture.cpp | 4 - src/mongo/db/repl/storage_interface_impl.cpp | 1 - src/mongo/db/s/config/initial_split_policy.cpp | 43 +-- .../db/s/config/initial_split_policy_test.cpp | 16 +- ...rding_catalog_manager_collection_operations.cpp | 1 - src/mongo/db/s/merge_chunks_command.cpp | 5 +- src/mongo/db/s/migration_source_manager.cpp | 18 +- src/mongo/db/s/shardsvr_shard_collection.cpp | 1 - src/mongo/db/service_context_d_test_fixture.cpp | 3 - src/mongo/db/service_entry_point_common.cpp | 1 - src/mongo/db/service_liaison.cpp | 1 - src/mongo/db/storage/storage_engine_impl.cpp | 1 - .../db/update/object_replace_executor_test.cpp | 1 - src/mongo/db/update/pipeline_executor_test.cpp | 1 - src/mongo/db/update/update_node_test_fixture.h | 6 - src/mongo/db/vector_clock.cpp | 13 + src/mongo/db/vector_clock.h | 7 + src/mongo/db/vector_clock_test.cpp | 335 ++++++++++++++++++++ src/mongo/db/vector_clock_test_fixture.cpp | 107 +++++++ src/mongo/db/vector_clock_test_fixture.h | 83 +++++ src/mongo/dbtests/dbtests.cpp | 4 - src/mongo/dbtests/querytests.cpp | 1 - src/mongo/embedded/embedded.cpp | 4 - .../embedded/stitch_support/stitch_support.cpp | 3 - src/mongo/rpc/metadata.cpp | 1 - src/mongo/s/catalog_cache.cpp | 1 - src/mongo/s/cluster_commands_helpers.cpp | 1 - .../s/commands/cluster_command_test_fixture.cpp | 5 +- src/mongo/s/commands/cluster_write_cmd.cpp | 1 - src/mongo/s/commands/strategy.cpp | 7 +- src/mongo/s/grid.cpp | 8 +- src/mongo/s/mongos_main.cpp | 3 - src/mongo/s/query/cluster_aggregate.cpp | 1 - src/mongo/s/query/cluster_find.cpp | 1 - src/mongo/s/query/sharded_agg_test_fixture.h | 3 - src/mongo/s/sessions_collection_sharded_test.cpp | 3 +- src/mongo/s/sharding_initialization.cpp | 1 - src/mongo/s/transaction_router.cpp | 9 +- src/mongo/s/transaction_router_test.cpp | 5 +- src/mongo/s/write_ops/batch_write_exec_test.cpp | 3 - 72 files changed, 662 insertions(+), 866 deletions(-) delete mode 100644 src/mongo/db/logical_clock.cpp delete mode 100644 src/mongo/db/logical_clock.h delete mode 100644 src/mongo/db/logical_clock_test.cpp delete mode 100644 src/mongo/db/logical_clock_test_fixture.cpp delete mode 100644 src/mongo/db/logical_clock_test_fixture.h create mode 100644 src/mongo/db/vector_clock_test.cpp create mode 100644 src/mongo/db/vector_clock_test_fixture.cpp create mode 100644 src/mongo/db/vector_clock_test_fixture.h diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript index 0d27639c637..66aa6d8cf13 100644 --- a/src/mongo/db/SConscript +++ b/src/mongo/db/SConscript @@ -1655,7 +1655,6 @@ env.Library( 'key_generator.cpp', 'keys_collection_cache.cpp', 'keys_collection_manager.cpp', - 'logical_clock.cpp', 'logical_time_validator.cpp', 'vector_clock.cpp', env.Idlc('keys_collection_manager.idl')[0], @@ -1741,9 +1740,9 @@ env.Library( ) env.Library( - target= 'logical_clock_test_fixture', + target= 'vector_clock_test_fixture', source= [ - 'logical_clock_test_fixture.cpp', + 'vector_clock_test_fixture.cpp', ], LIBDEPS= [ '$BUILD_DIR/mongo/db/auth/authmocks', @@ -2226,7 +2225,6 @@ envWithAsio.CppUnitTest( 'index_builds_coordinator_mongod_test.cpp', 'keypattern_test.cpp', 'keys_collection_document_test.cpp', - 'logical_clock_test.cpp', 'logical_session_cache_test.cpp', 'logical_session_id_test.cpp', 'logical_time_test.cpp', @@ -2253,6 +2251,7 @@ envWithAsio.CppUnitTest( 'transaction_participant_test.cpp', 'update_index_data_test.cpp', 'vector_clock_mongod_test.cpp', + 'vector_clock_test.cpp', 'write_concern_options_test.cpp', 'error_labels_test.cpp', env.Idlc('commands_test_example.idl')[0], @@ -2290,7 +2289,6 @@ envWithAsio.CppUnitTest( 'index_builds_coordinator_mongod', 'keys_collection_client_direct', 'keys_collection_document', - 'logical_clock_test_fixture', 'logical_session_cache', 'logical_session_cache_impl', 'logical_session_id', @@ -2331,6 +2329,7 @@ envWithAsio.CppUnitTest( 'transaction', 'update_index_data', 'vector_clock', + 'vector_clock_test_fixture', 'write_concern_options', 'write_ops', ], diff --git a/src/mongo/db/auth/auth_op_observer_test.cpp b/src/mongo/db/auth/auth_op_observer_test.cpp index 8527a96af52..6069ee02f13 100644 --- a/src/mongo/db/auth/auth_op_observer_test.cpp +++ b/src/mongo/db/auth/auth_op_observer_test.cpp @@ -37,7 +37,6 @@ #include "mongo/db/dbdirectclient.h" #include "mongo/db/keys_collection_client_sharded.h" #include "mongo/db/keys_collection_manager.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_time_validator.h" #include "mongo/db/repl/oplog.h" #include "mongo/db/repl/oplog_interface_local.h" diff --git a/src/mongo/db/catalog/index_build_block.cpp b/src/mongo/db/catalog/index_build_block.cpp index cbb504241b3..9fa6361b82b 100644 --- a/src/mongo/db/catalog/index_build_block.cpp +++ b/src/mongo/db/catalog/index_build_block.cpp @@ -40,11 +40,11 @@ #include "mongo/db/catalog_raii.h" #include "mongo/db/db_raii.h" #include "mongo/db/index/index_descriptor.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/operation_context.h" #include "mongo/db/query/collection_query_info.h" #include "mongo/db/storage/durable_catalog.h" #include "mongo/db/ttl_collection_cache.h" +#include "mongo/db/vector_clock.h" #include "mongo/logv2/log.h" #include "mongo/util/assert_util.h" @@ -228,7 +228,7 @@ void IndexBuildBlock::success(OperationContext* opCtx, Collection* collection) { // timestamp. We use the cluster time since it's guaranteed to be greater than the // time of the index build. It is possible the cluster time could be in the future, // and we will need to do another write to reach the minimum visible snapshot. - commitTime = LogicalClock::getClusterTimeForReplicaSet(svcCtx).asTimestamp(); + commitTime = VectorClock::getClusterTimeForReplicaSet(svcCtx).asTimestamp(); } LOGV2(20345, diff --git a/src/mongo/db/catalog/index_catalog_entry_impl.cpp b/src/mongo/db/catalog/index_catalog_entry_impl.cpp index d1603408b7c..7c604a98a99 100644 --- a/src/mongo/db/catalog/index_catalog_entry_impl.cpp +++ b/src/mongo/db/catalog/index_catalog_entry_impl.cpp @@ -42,7 +42,6 @@ #include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/index/index_access_method.h" #include "mongo/db/index/index_descriptor.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/matcher/expression.h" #include "mongo/db/matcher/expression_parser.h" #include "mongo/db/multi_key_path_tracker.h" diff --git a/src/mongo/db/catalog/index_catalog_impl.cpp b/src/mongo/db/catalog/index_catalog_impl.cpp index d90f7977674..7855f9afb4d 100644 --- a/src/mongo/db/catalog/index_catalog_impl.cpp +++ b/src/mongo/db/catalog/index_catalog_impl.cpp @@ -56,7 +56,6 @@ #include "mongo/db/index_names.h" #include "mongo/db/jsobj.h" #include "mongo/db/keypattern.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/matcher/expression.h" #include "mongo/db/operation_context.h" #include "mongo/db/ops/delete.h" @@ -74,6 +73,7 @@ #include "mongo/db/storage/storage_engine_init.h" #include "mongo/db/storage/storage_util.h" #include "mongo/db/ttl_collection_cache.h" +#include "mongo/db/vector_clock.h" #include "mongo/logv2/log.h" #include "mongo/util/assert_util.h" #include "mongo/util/fail_point.h" @@ -1026,7 +1026,7 @@ public: // a commit timestamp. We use the cluster time since it's guaranteed to be greater // than the time of the index removal. It is possible the cluster time could be in the // future, and we will need to do another write to reach the minimum visible snapshot. - commitTime = LogicalClock::getClusterTimeForReplicaSet(_opCtx).asTimestamp(); + commitTime = VectorClock::getClusterTimeForReplicaSet(_opCtx).asTimestamp(); } _entry->setDropped(); _collection->setMinimumVisibleSnapshot(commitTime.get()); diff --git a/src/mongo/db/commands/dbhash.cpp b/src/mongo/db/commands/dbhash.cpp index ad150d7c116..be9243982ca 100644 --- a/src/mongo/db/commands/dbhash.cpp +++ b/src/mongo/db/commands/dbhash.cpp @@ -44,7 +44,6 @@ #include "mongo/db/commands/test_commands_enabled.h" #include "mongo/db/db_raii.h" #include "mongo/db/exec/working_set_common.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/namespace_string.h" #include "mongo/db/query/internal_plans.h" #include "mongo/db/repl/replication_coordinator.h" diff --git a/src/mongo/db/commands/drop_indexes.cpp b/src/mongo/db/commands/drop_indexes.cpp index eebf122c494..b0d2a25e7e6 100644 --- a/src/mongo/db/commands/drop_indexes.cpp +++ b/src/mongo/db/commands/drop_indexes.cpp @@ -47,10 +47,10 @@ #include "mongo/db/db_raii.h" #include "mongo/db/index/index_descriptor.h" #include "mongo/db/index_builds_coordinator.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/op_observer.h" #include "mongo/db/service_context.h" #include "mongo/db/storage/durable_catalog.h" +#include "mongo/db/vector_clock.h" #include "mongo/db/views/view_catalog.h" #include "mongo/logv2/log.h" #include "mongo/util/exit_code.h" @@ -262,7 +262,7 @@ public: // This was also done when dropAllIndexes() committed, but we need to ensure that no one // tries to read in the intermediate state where all indexes are newer than the current // snapshot so are unable to be used. - auto clusterTime = LogicalClock::getClusterTimeForReplicaSet(opCtx).asTimestamp(); + auto clusterTime = VectorClock::getClusterTimeForReplicaSet(opCtx).asTimestamp(); collection.getWritableCollection()->setMinimumVisibleSnapshot(clusterTime); collection.commitToCatalog(); diff --git a/src/mongo/db/commands/snapshot_management.cpp b/src/mongo/db/commands/snapshot_management.cpp index be2e432c243..43e2a07e01a 100644 --- a/src/mongo/db/commands/snapshot_management.cpp +++ b/src/mongo/db/commands/snapshot_management.cpp @@ -34,11 +34,11 @@ #include "mongo/db/commands.h" #include "mongo/db/commands/test_commands_enabled.h" #include "mongo/db/concurrency/d_concurrency.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/operation_context.h" #include "mongo/db/repl/replication_coordinator.h" #include "mongo/db/service_context.h" #include "mongo/db/storage/snapshot_manager.h" +#include "mongo/db/vector_clock.h" namespace mongo { class CmdMakeSnapshot final : public BasicCommand { @@ -77,7 +77,7 @@ public: Lock::GlobalLock lk(opCtx, MODE_IX); - auto name = LogicalClock::getClusterTimeForReplicaSet(opCtx).asTimestamp(); + auto name = VectorClock::getClusterTimeForReplicaSet(opCtx).asTimestamp(); result.append("name", static_cast(name.asULL())); return true; diff --git a/src/mongo/db/key_generator.cpp b/src/mongo/db/key_generator.cpp index 7c95d210bfa..3e899fd888b 100644 --- a/src/mongo/db/key_generator.cpp +++ b/src/mongo/db/key_generator.cpp @@ -33,8 +33,8 @@ #include "mongo/client/read_preference.h" #include "mongo/db/keys_collection_client.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/operation_context.h" +#include "mongo/db/vector_clock.h" #include "mongo/s/client/shard_registry.h" #include "mongo/util/fail_point.h" @@ -80,8 +80,8 @@ Status KeyGenerator::generateNewKeysIfNeeded(OperationContext* opCtx) { return {ErrorCodes::FailPointEnabled, "key generation disabled"}; } - auto currentTime = LogicalClock::get(opCtx)->getClusterTime(); - auto keyStatus = _client->getNewKeys(opCtx, _purpose, currentTime, false); + const auto currentTime = VectorClock::get(opCtx)->getTime(); + auto keyStatus = _client->getNewKeys(opCtx, _purpose, currentTime.clusterTime(), false); if (!keyStatus.isOK()) { return keyStatus.getStatus(); @@ -92,10 +92,10 @@ Status KeyGenerator::generateNewKeysIfNeeded(OperationContext* opCtx) { LogicalTime currentKeyExpiresAt; - long long keyId = currentTime.asTimestamp().asLL(); + long long keyId = currentTime.clusterTime().asTimestamp().asLL(); if (keyIter == newKeys.cend()) { - currentKeyExpiresAt = addSeconds(currentTime, _keyValidForInterval); + currentKeyExpiresAt = addSeconds(currentTime.clusterTime(), _keyValidForInterval); auto status = insertNewKey(opCtx, _client, keyId, _purpose, currentKeyExpiresAt); if (!status.isOK()) { @@ -103,8 +103,8 @@ Status KeyGenerator::generateNewKeysIfNeeded(OperationContext* opCtx) { } keyId++; - } else if (keyIter->getExpiresAt() < currentTime) { - currentKeyExpiresAt = addSeconds(currentTime, _keyValidForInterval); + } else if (keyIter->getExpiresAt() < currentTime.clusterTime()) { + currentKeyExpiresAt = addSeconds(currentTime.clusterTime(), _keyValidForInterval); auto status = insertNewKey(opCtx, _client, keyId, _purpose, currentKeyExpiresAt); if (!status.isOK()) { @@ -128,7 +128,7 @@ Status KeyGenerator::generateNewKeysIfNeeded(OperationContext* opCtx) { if (!status.isOK()) { return status; } - } else if (keyIter->getExpiresAt() < currentTime) { + } else if (keyIter->getExpiresAt() < currentTime.clusterTime()) { currentKeyExpiresAt = addSeconds(currentKeyExpiresAt, _keyValidForInterval); auto status = insertNewKey(opCtx, _client, keyId, _purpose, currentKeyExpiresAt); diff --git a/src/mongo/db/keys_collection_client_direct.cpp b/src/mongo/db/keys_collection_client_direct.cpp index 7b00475749a..2ee8b003bf8 100644 --- a/src/mongo/db/keys_collection_client_direct.cpp +++ b/src/mongo/db/keys_collection_client_direct.cpp @@ -41,7 +41,6 @@ #include "mongo/client/read_preference.h" #include "mongo/db/dbdirectclient.h" #include "mongo/db/keys_collection_document.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_time.h" #include "mongo/db/operation_context.h" #include "mongo/db/service_context.h" diff --git a/src/mongo/db/keys_collection_manager.cpp b/src/mongo/db/keys_collection_manager.cpp index 75bade8e329..86a95a1a864 100644 --- a/src/mongo/db/keys_collection_manager.cpp +++ b/src/mongo/db/keys_collection_manager.cpp @@ -37,10 +37,10 @@ #include "mongo/db/key_generator.h" #include "mongo/db/keys_collection_cache.h" #include "mongo/db/keys_collection_client.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_time.h" #include "mongo/db/operation_context.h" #include "mongo/db/service_context.h" +#include "mongo/db/vector_clock.h" #include "mongo/logv2/log.h" #include "mongo/util/concurrency/idle_thread_block.h" #include "mongo/util/fail_point.h" @@ -252,12 +252,12 @@ void KeysCollectionManager::PeriodicRunner::_doPeriodicRefresh(ServiceContext* s if (latestKeyStatusWith.getStatus().isOK()) { errorCount = 0; const auto& latestKey = latestKeyStatusWith.getValue(); - auto currentTime = LogicalClock::get(service)->getClusterTime(); + const auto currentTime = VectorClock::get(service)->getTime(); _hasSeenKeys.store(true); nextWakeup = keys_collection_manager_util::howMuchSleepNeedFor( - currentTime, latestKey.getExpiresAt(), refreshInterval); + currentTime.clusterTime(), latestKey.getExpiresAt(), refreshInterval); } else { errorCount += 1; nextWakeup = Milliseconds(kRefreshIntervalIfErrored.count() * errorCount); diff --git a/src/mongo/db/keys_collection_manager_sharding_test.cpp b/src/mongo/db/keys_collection_manager_sharding_test.cpp index ba24d2bf03f..dc19e7f5c9e 100644 --- a/src/mongo/db/keys_collection_manager_sharding_test.cpp +++ b/src/mongo/db/keys_collection_manager_sharding_test.cpp @@ -381,7 +381,7 @@ TEST(KeysCollectionManagerUtilTest, HowMuchSleepNeededForCalculationDoesNotOverf auto defaultKeysIntervalSeconds = Seconds(KeysRotationIntervalSec); // Mock inputs that would have caused an overflow without the changes from SERVER-48709. - // "currentTime" is the current logical time in the LogicalClock, which will typically be close + // "currentTime" is the current clusterTime in the VectorClock, which will typically be close // to a timestamp constructed from the number of seconds since the unix epoch. "latestExpiredAt" // is the highest expiration logical time of any key, which will at most be currentTime + // (default key rotation interval * 2) because two valid keys are kept at a time. "interval" is diff --git a/src/mongo/db/logical_clock.cpp b/src/mongo/db/logical_clock.cpp deleted file mode 100644 index 41a7d40b5d2..00000000000 --- a/src/mongo/db/logical_clock.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * 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 - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * . - * - * 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 Server Side 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_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kDefault - -#include "mongo/platform/basic.h" - -#include "mongo/db/logical_clock.h" - -#include "mongo/base/status.h" -#include "mongo/db/global_settings.h" -#include "mongo/db/operation_context.h" -#include "mongo/db/service_context.h" -#include "mongo/db/time_proof_service.h" -#include "mongo/db/vector_clock.h" -#include "mongo/logv2/log.h" - -namespace mongo { - -namespace { -const auto getLogicalClock = ServiceContext::declareDecoration>(); -} // namespace - -LogicalTime LogicalClock::getClusterTimeForReplicaSet(ServiceContext* svcCtx) { - if (getGlobalReplSettings().usingReplSets()) { - return get(svcCtx)->getClusterTime(); - } - - return {}; -} - -LogicalTime LogicalClock::getClusterTimeForReplicaSet(OperationContext* opCtx) { - return getClusterTimeForReplicaSet(opCtx->getClient()->getServiceContext()); -} - -LogicalClock* LogicalClock::get(ServiceContext* service) { - return getLogicalClock(service).get(); -} - -LogicalClock* LogicalClock::get(OperationContext* ctx) { - return get(ctx->getClient()->getServiceContext()); -} - -void LogicalClock::set(ServiceContext* service, std::unique_ptr clockArg) { - auto& clock = getLogicalClock(service); - clock = std::move(clockArg); -} - -LogicalClock::LogicalClock(ServiceContext* service) : _service(service) {} - -LogicalTime LogicalClock::getClusterTime() { - auto time = VectorClock::get(_service)->getTime(); - return time.clusterTime(); -} - -} // namespace mongo diff --git a/src/mongo/db/logical_clock.h b/src/mongo/db/logical_clock.h deleted file mode 100644 index 059a9dcdfd6..00000000000 --- a/src/mongo/db/logical_clock.h +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * 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 - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * . - * - * 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 Server Side 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. - */ - -#pragma once - -#include "mongo/db/logical_time.h" -#include "mongo/platform/mutex.h" - -namespace mongo { -class ServiceContext; -class OperationContext; - - -/** - * LogicalClock provides a legacy interface to the cluster time, which is now provided by the - * VectorClock class. - * - * TODO SERVER-48433: Remove this legacy LogicalClock interface. - */ -class LogicalClock { -public: - // Decorate ServiceContext with LogicalClock instance. - static LogicalClock* get(ServiceContext* service); - static LogicalClock* get(OperationContext* ctx); - static void set(ServiceContext* service, std::unique_ptr logicalClock); - - /** - * Returns the current cluster time if this is a replica set node, otherwise returns a null - * logical time. - */ - static LogicalTime getClusterTimeForReplicaSet(ServiceContext* svcCtx); - static LogicalTime getClusterTimeForReplicaSet(OperationContext* opCtx); - - /** - * Creates an instance of LogicalClock. - */ - LogicalClock(ServiceContext*); - - /** - * Returns the current clusterTime. - */ - LogicalTime getClusterTime(); - -private: - ServiceContext* const _service; -}; - -} // namespace mongo diff --git a/src/mongo/db/logical_clock_test.cpp b/src/mongo/db/logical_clock_test.cpp deleted file mode 100644 index af475c5439e..00000000000 --- a/src/mongo/db/logical_clock_test.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * 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 - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * . - * - * 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 Server Side 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_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kTest - -#include "mongo/platform/basic.h" - -#include - -#include "mongo/bson/bsonobj.h" -#include "mongo/bson/timestamp.h" -#include "mongo/db/dbdirectclient.h" -#include "mongo/db/logical_clock.h" -#include "mongo/db/logical_clock_gen.h" -#include "mongo/db/logical_clock_test_fixture.h" -#include "mongo/db/logical_time.h" -#include "mongo/db/repl/replication_coordinator_mock.h" -#include "mongo/db/vector_clock_mutable.h" -#include "mongo/unittest/unittest.h" -#include "mongo/util/clock_source_mock.h" - -namespace mongo { -namespace { - -const NamespaceString kDummyNamespaceString("test", "foo"); - -using LogicalClockTest = LogicalClockTestFixture; - -constexpr unsigned maxVal = std::numeric_limits::max(); - -LogicalTime buildLogicalTime(unsigned secs, unsigned inc) { - return LogicalTime(Timestamp(secs, inc)); -} - -// Check that the initial time does not change during logicalClock creation. -TEST_F(LogicalClockTest, roundtrip) { - Timestamp tX(1); - auto time = LogicalTime(tX); - - VectorClockMutable::get(getServiceContext())->tickClusterTimeTo(time); - auto storedTime(getClock()->getClusterTime()); - - ASSERT_TRUE(storedTime == time); -} - -// Verify the reserve ticks functionality. -TEST_F(LogicalClockTest, reserveTicks) { - // Set clock to a non-zero time, so we can verify wall clock synchronization. - setMockClockSourceTime(Date_t::fromMillisSinceEpoch(10 * 1000)); - - auto t1 = VectorClockMutable::get(getServiceContext())->tickClusterTime(1); - auto t2(getClock()->getClusterTime()); - ASSERT_TRUE(t1 == t2); - - // Make sure we synchronized with the wall clock. - ASSERT_TRUE(t2.asTimestamp().getSecs() == 10); - - auto t3 = VectorClockMutable::get(getServiceContext())->tickClusterTime(1); - t1.addTicks(1); - ASSERT_TRUE(t3 == t1); - - t3 = VectorClockMutable::get(getServiceContext())->tickClusterTime(100); - t1.addTicks(1); - ASSERT_TRUE(t3 == t1); - - t3 = VectorClockMutable::get(getServiceContext())->tickClusterTime(1); - t1.addTicks(100); - ASSERT_TRUE(t3 == t1); - - // Ensure overflow to a new second. - auto initTimeSecs = getClock()->getClusterTime().asTimestamp().getSecs(); - VectorClockMutable::get(getServiceContext())->tickClusterTime((1U << 31) - 1); - auto newTimeSecs = getClock()->getClusterTime().asTimestamp().getSecs(); - ASSERT_TRUE(newTimeSecs == initTimeSecs + 1); -} - -// Verify the advanceClusterTime functionality. -TEST_F(LogicalClockTest, advanceClusterTime) { - auto t1 = VectorClockMutable::get(getServiceContext())->tickClusterTime(1); - t1.addTicks(100); - advanceClusterTime(t1); - ASSERT_TRUE(t1 == getClock()->getClusterTime()); -} - -// Verify rate limiter rejects cluster times whose seconds values are too far ahead. -TEST_F(LogicalClockTest, RateLimiterRejectsLogicalTimesTooFarAhead) { - setMockClockSourceTime(Date_t::fromMillisSinceEpoch(10 * 1000)); - - Timestamp tooFarAheadTimestamp( - durationCount(getMockClockSourceTime().toDurationSinceEpoch()) + - kMaxAcceptableLogicalClockDriftSecsDefault + - 10, // Add 10 seconds to ensure limit is exceeded. - 1); - LogicalTime t1(tooFarAheadTimestamp); - - ASSERT_THROWS_CODE( - advanceClusterTime(t1), DBException, ErrorCodes::ClusterTimeFailsRateLimiter); -} - -// Verify cluster time can be initialized to a very old time. -TEST_F(LogicalClockTest, InitFromTrustedSourceCanAcceptVeryOldLogicalTime) { - setMockClockSourceTime(Date_t::fromMillisSinceEpoch( - durationCount(Seconds(kMaxAcceptableLogicalClockDriftSecsDefault)) * 10 * 1000)); - - Timestamp veryOldTimestamp( - durationCount(getMockClockSourceTime().toDurationSinceEpoch()) - - (kMaxAcceptableLogicalClockDriftSecsDefault * 5)); - auto veryOldTime = LogicalTime(veryOldTimestamp); - VectorClockMutable::get(getServiceContext())->tickClusterTimeTo(veryOldTime); - - ASSERT_TRUE(getClock()->getClusterTime() == veryOldTime); -} - -// Verify writes to the oplog advance cluster time. -TEST_F(LogicalClockTest, WritesToOplogAdvanceClusterTime) { - Timestamp tX(1, 0); - auto initialTime = LogicalTime(tX); - - VectorClockMutable::get(getServiceContext())->tickClusterTimeTo(initialTime); - ASSERT_TRUE(getClock()->getClusterTime() == initialTime); - - getDBClient()->insert(kDummyNamespaceString.ns(), BSON("x" << 1)); - ASSERT_TRUE(getClock()->getClusterTime() > initialTime); - ASSERT_EQ(getClock()->getClusterTime().asTimestamp(), - replicationCoordinator()->getMyLastAppliedOpTime().getTimestamp()); -} - -// Tests the scenario where an admin incorrectly sets the wall clock more than -// maxAcceptableLogicalClockDriftSecs in the past at startup, and cluster time is initialized to -// the incorrect past time, then the admin resets the clock to the current time. In this case, -// cluster time can be advanced through metadata as long as the new time isn't -// maxAcceptableLogicalClockDriftSecs ahead of the correct current wall clock time, since the rate -// limiter compares new times to the wall clock, not the cluster time. -TEST_F(LogicalClockTest, WallClockSetTooFarInPast) { - auto oneDay = Seconds(24 * 60 * 60); - - // Current wall clock and cluster time. - auto currentSecs = Seconds(kMaxAcceptableLogicalClockDriftSecsDefault) * 10; - LogicalTime currentTime(Timestamp(currentSecs, 0)); - - // Set wall clock more than maxAcceptableLogicalClockDriftSecs seconds in the past. - auto pastSecs = currentSecs - Seconds(kMaxAcceptableLogicalClockDriftSecsDefault) - oneDay; - setMockClockSourceTime(Date_t::fromDurationSinceEpoch(pastSecs)); - - // If cluster time is either uninitialized or even farther in the past, a write would set - // cluster time more than maxAcceptableLogicalClockDriftSecs in the past. - getDBClient()->insert(kDummyNamespaceString.ns(), BSON("x" << 1)); - ASSERT_TRUE(getClock()->getClusterTime() < - LogicalTime(Timestamp( - currentSecs - Seconds(kMaxAcceptableLogicalClockDriftSecsDefault), 0))); - - // Set wall clock to the current time on the affected node. - setMockClockSourceTime(Date_t::fromDurationSinceEpoch(currentSecs)); - - // Verify that maxAcceptableLogicalClockDriftSecs parameter does not need to be increased to - // advance cluster time through metadata back to the current time. - advanceClusterTime(currentTime); - ASSERT_TRUE(getClock()->getClusterTime() == currentTime); -} - -// Tests the scenario where an admin incorrectly sets the wall clock more than -// maxAcceptableLogicalClockDriftSecs in the future and a write is accepted, advancing cluster -// time, then the admin resets the clock to the current time. In this case, cluster time cannot be -// advanced through metadata unless the drift parameter is increased. -TEST_F(LogicalClockTest, WallClockSetTooFarInFuture) { - auto oneDay = Seconds(24 * 60 * 60); - - // Current wall clock and cluster time. - auto currentSecs = Seconds(kMaxAcceptableLogicalClockDriftSecsDefault) * 10; - LogicalTime currentTime(Timestamp(currentSecs, 0)); - - // Set wall clock more than maxAcceptableLogicalClockDriftSecs seconds in the future. - auto futureSecs = currentSecs + Seconds(kMaxAcceptableLogicalClockDriftSecsDefault) + oneDay; - setMockClockSourceTime(Date_t::fromDurationSinceEpoch(futureSecs)); - - // A write gets through and advances cluster time more than maxAcceptableLogicalClockDriftSecs - // in the future. - getDBClient()->insert(kDummyNamespaceString.ns(), BSON("x" << 1)); - ASSERT_TRUE(getClock()->getClusterTime() > - LogicalTime(Timestamp( - currentSecs + Seconds(kMaxAcceptableLogicalClockDriftSecsDefault), 0))); - - // Set wall clock to the current time on the affected node. - setMockClockSourceTime(Date_t::fromDurationSinceEpoch(currentSecs)); - - // Verify that maxAcceptableLogicalClockDriftSecs parameter has to be increased to advance - // cluster time through metadata. - auto nextTime = getClock()->getClusterTime(); - nextTime.addTicks(1); // The next lowest cluster time. - - ASSERT_THROWS_CODE( - advanceClusterTime(nextTime), DBException, ErrorCodes::ClusterTimeFailsRateLimiter); - - // Set wall clock to the current time + 1 day to simulate increasing the - // maxAcceptableLogicalClockDriftSecs parameter, which can only be set at startup, and verify - // time can be advanced through metadata again. - setMockClockSourceTime(Date_t::fromDurationSinceEpoch(currentSecs + oneDay)); - - advanceClusterTime(nextTime); - ASSERT_TRUE(getClock()->getClusterTime() == nextTime); -} - -// Verify the behavior of advancing cluster time around the max allowed values. -TEST_F(LogicalClockTest, ReserveTicksBehaviorAroundMaxTime) { - // Verify clock can be advanced near the max values. - - // Can always advance to the max value for the inc field. - resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal - 1, maxVal - 1)); - VectorClockMutable::get(getServiceContext())->tickClusterTime(1); - ASSERT_EQ(getClock()->getClusterTime(), buildLogicalTime(maxVal - 1, maxVal)); - - resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal - 1, maxVal - 5)); - VectorClockMutable::get(getServiceContext())->tickClusterTime(5); - ASSERT_EQ(getClock()->getClusterTime(), buildLogicalTime(maxVal - 1, maxVal)); - - resetClock()->tickClusterTimeTo(buildLogicalTime(0, maxVal - 1)); - VectorClockMutable::get(getServiceContext())->tickClusterTime(1); - ASSERT_EQ(getClock()->getClusterTime(), buildLogicalTime(0, maxVal)); - - // Can overflow inc into seconds to reach max seconds value. - resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal - 1, maxVal)); - VectorClockMutable::get(getServiceContext())->tickClusterTime(1); - ASSERT_EQ(getClock()->getClusterTime(), buildLogicalTime(maxVal, 1)); - - resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal - 1, maxVal - 5)); - VectorClockMutable::get(getServiceContext())->tickClusterTime(10); - ASSERT_EQ(getClock()->getClusterTime(), buildLogicalTime(maxVal, 10)); - - resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal - 1, 1)); - VectorClockMutable::get(getServiceContext())->tickClusterTime(maxVal); - ASSERT_EQ(getClock()->getClusterTime(), buildLogicalTime(maxVal, maxVal)); - - // Can advance inc field when seconds field is at the max value. - resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal, 1)); - VectorClockMutable::get(getServiceContext())->tickClusterTime(1); - ASSERT_EQ(getClock()->getClusterTime(), buildLogicalTime(maxVal, 2)); - - resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal, 1)); - VectorClockMutable::get(getServiceContext())->tickClusterTime(100); - ASSERT_EQ(getClock()->getClusterTime(), buildLogicalTime(maxVal, 101)); - - // Can advance to the max value for both the inc and seconds fields. - resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal, maxVal - 1)); - VectorClockMutable::get(getServiceContext())->tickClusterTime(1); - ASSERT_EQ(getClock()->getClusterTime(), buildLogicalTime(maxVal, maxVal)); - - resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal, maxVal - 5)); - VectorClockMutable::get(getServiceContext())->tickClusterTime(5); - ASSERT_EQ(getClock()->getClusterTime(), buildLogicalTime(maxVal, maxVal)); - - // Verify scenarios where the clock cannot be advanced. - - // Can't overflow inc into seconds when seconds field is at the max value. - resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal, maxVal)); - ASSERT_THROWS(VectorClockMutable::get(getServiceContext())->tickClusterTime(1), DBException); - ASSERT_EQ(getClock()->getClusterTime(), buildLogicalTime(maxVal, maxVal)); - - resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal, maxVal)); - ASSERT_THROWS(VectorClockMutable::get(getServiceContext())->tickClusterTime(5), DBException); - ASSERT_EQ(getClock()->getClusterTime(), buildLogicalTime(maxVal, maxVal)); - - resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal, maxVal - 1)); - ASSERT_THROWS(VectorClockMutable::get(getServiceContext())->tickClusterTime(2), DBException); - ASSERT_EQ(getClock()->getClusterTime(), buildLogicalTime(maxVal, maxVal - 1)); - - resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal, maxVal - 11)); - ASSERT_THROWS(VectorClockMutable::get(getServiceContext())->tickClusterTime(12), DBException); - ASSERT_EQ(getClock()->getClusterTime(), buildLogicalTime(maxVal, maxVal - 11)); -} - -// Verify behavior of advancing cluster time when the wall clock is near the max allowed value. -TEST_F(LogicalClockTest, ReserveTicksBehaviorWhenWallClockNearMaxTime) { - // Can be set to the max possible time by catching up to the wall clock. - setMockClockSourceTime(Date_t::fromDurationSinceEpoch(Seconds(maxVal))); - - resetClock()->tickClusterTimeTo(buildLogicalTime(1, 1)); - VectorClockMutable::get(getServiceContext())->tickClusterTime(1); - ASSERT_EQ(getClock()->getClusterTime(), buildLogicalTime(maxVal, 1)); - - // Should fail when wall clock would advance cluster time beyond the max allowed time. - setMockClockSourceTime(Date_t::max()); - - resetClock()->tickClusterTimeTo(buildLogicalTime(1, 1)); - ASSERT_THROWS(VectorClockMutable::get(getServiceContext())->tickClusterTime(1), DBException); - ASSERT_EQ(getClock()->getClusterTime(), buildLogicalTime(1, 1)); -} - -// Verify the clock rejects cluster times greater than the max allowed time. -TEST_F(LogicalClockTest, RejectsLogicalTimesGreaterThanMaxTime) { - // A cluster time can be greater than the maximum value allowed because the signed integer - // maximum is used for legacy compatibility, but these fields are stored as unsigned integers. - auto beyondMaxTime = buildLogicalTime(maxVal + 1, maxVal + 1); - - // The clock can't be initialized to a time greater than the max possible. - resetClock(); - ASSERT_THROWS(VectorClockMutable::get(getServiceContext())->tickClusterTimeTo(beyondMaxTime), - DBException); - ASSERT_TRUE(getClock()->getClusterTime() == LogicalTime()); - - // The time can't be advanced through metadata to a time greater than the max possible. - // Advance the wall clock close enough to the new value so the rate check is passed. - auto almostMaxSecs = - Seconds(maxVal) - Seconds(kMaxAcceptableLogicalClockDriftSecsDefault) + Seconds(10); - setMockClockSourceTime(Date_t::fromDurationSinceEpoch(almostMaxSecs)); - ASSERT_THROWS(advanceClusterTime(beyondMaxTime), DBException); - ASSERT_TRUE(getClock()->getClusterTime() == LogicalTime()); -} - -} // unnamed namespace -} // namespace mongo diff --git a/src/mongo/db/logical_clock_test_fixture.cpp b/src/mongo/db/logical_clock_test_fixture.cpp deleted file mode 100644 index 99d3ee0e7b9..00000000000 --- a/src/mongo/db/logical_clock_test_fixture.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * 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 - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * . - * - * 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 Server Side 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 - -#include "mongo/db/dbdirectclient.h" -#include "mongo/db/logical_clock.h" -#include "mongo/db/logical_time.h" -#include "mongo/db/repl/replication_coordinator_mock.h" -#include "mongo/db/service_context.h" -#include "mongo/db/signed_logical_time.h" -#include "mongo/db/time_proof_service.h" -#include "mongo/db/vector_clock_mutable.h" -#include "mongo/unittest/unittest.h" -#include "mongo/util/clock_source_mock.h" - -namespace mongo { - -LogicalClockTestFixture::LogicalClockTestFixture() = default; - -LogicalClockTestFixture::~LogicalClockTestFixture() = default; - -void LogicalClockTestFixture::setUp() { - ShardingMongodTestFixture::setUp(); - - auto service = getServiceContext(); - - auto logicalClock = std::make_unique(service); - LogicalClock::set(service, std::move(logicalClock)); - _clock = LogicalClock::get(service); - - service->setFastClockSource(std::make_unique(_mockClockSource)); - service->setPreciseClockSource(std::make_unique(_mockClockSource)); - - _dbDirectClient = std::make_unique(operationContext()); - - ASSERT_OK(replicationCoordinator()->setFollowerMode(repl::MemberState::RS_PRIMARY)); -} - -void LogicalClockTestFixture::tearDown() { - _dbDirectClient.reset(); - ShardingMongodTestFixture::tearDown(); -} - -VectorClockMutable* LogicalClockTestFixture::resetClock() { - auto service = getServiceContext(); - VectorClock::get(service)->resetVectorClock_forTest(); - return VectorClockMutable::get(service); -} - -void LogicalClockTestFixture::advanceClusterTime(LogicalTime newTime) { - VectorClock::get(getServiceContext())->advanceClusterTime_forTest(newTime); -} - -LogicalClock* LogicalClockTestFixture::getClock() const { - return _clock; -} - -ClockSourceMock* LogicalClockTestFixture::getMockClockSource() const { - return _mockClockSource.get(); -} - -void LogicalClockTestFixture::setMockClockSourceTime(Date_t time) const { - _mockClockSource->reset(time); -} - -Date_t LogicalClockTestFixture::getMockClockSourceTime() const { - return _mockClockSource->now(); -} - -DBDirectClient* LogicalClockTestFixture::getDBClient() const { - return _dbDirectClient.get(); -} - -} // namespace mongo diff --git a/src/mongo/db/logical_clock_test_fixture.h b/src/mongo/db/logical_clock_test_fixture.h deleted file mode 100644 index 4602ae629cd..00000000000 --- a/src/mongo/db/logical_clock_test_fixture.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * 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 - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * . - * - * 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 Server Side 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. - */ - -#pragma once - -#include "mongo/db/s/sharding_mongod_test_fixture.h" - -namespace mongo { - -class ClockSourceMock; -class DBDirectClient; -class LogicalClock; -class LogicalTime; -class VectorClockMutable; - -/** - * A test fixture that installs a LogicalClock instance with a TimeProofService onto a service - * context, in addition to the mock storage engine, network, and OpObserver provided by - * ShardingMongodTestFixture. - */ -class LogicalClockTestFixture : public ShardingMongodTestFixture { -public: - LogicalClockTestFixture(); - ~LogicalClockTestFixture(); - -protected: - /** - * Sets up this fixture as the primary node in a shard server replica set with a LogicalClock - * (with a TimeProofService), storage engine, DBClient, OpObserver, and a mocked clock source. - */ - void setUp() override; - - void tearDown() override; - - VectorClockMutable* resetClock(); - - void advanceClusterTime(LogicalTime newTime); - - LogicalClock* getClock() const; - - ClockSourceMock* getMockClockSource() const; - - void setMockClockSourceTime(Date_t time) const; - - Date_t getMockClockSourceTime() const; - - DBDirectClient* getDBClient() const; - -private: - LogicalClock* _clock; - std::shared_ptr _mockClockSource = std::make_shared(); - std::unique_ptr _dbDirectClient; -}; - -} // namespace mongo diff --git a/src/mongo/db/logical_time_validator.cpp b/src/mongo/db/logical_time_validator.cpp index 3f0e4d9b33b..56abc27ab46 100644 --- a/src/mongo/db/logical_time_validator.cpp +++ b/src/mongo/db/logical_time_validator.cpp @@ -52,7 +52,7 @@ namespace { MONGO_FAIL_POINT_DEFINE(throwClientDisconnectInSignLogicalTimeForExternalClients); -const auto getLogicalClockValidator = +const auto getLogicalTimeValidator = ServiceContext::declareDecoration>(); Mutex validatorMutex; // protects access to decoration instance of LogicalTimeValidator. @@ -72,7 +72,7 @@ Milliseconds kRefreshIntervalIfErrored(200); LogicalTimeValidator* LogicalTimeValidator::get(ServiceContext* service) { stdx::lock_guard lk(validatorMutex); - return getLogicalClockValidator(service).get(); + return getLogicalTimeValidator(service).get(); } LogicalTimeValidator* LogicalTimeValidator::get(OperationContext* ctx) { @@ -82,7 +82,7 @@ LogicalTimeValidator* LogicalTimeValidator::get(OperationContext* ctx) { void LogicalTimeValidator::set(ServiceContext* service, std::unique_ptr newValidator) { stdx::lock_guard lk(validatorMutex); - auto& validator = getLogicalClockValidator(service); + auto& validator = getLogicalTimeValidator(service); validator = std::move(newValidator); } diff --git a/src/mongo/db/mongod_main.cpp b/src/mongo/db/mongod_main.cpp index 74bbc372882..d4a02657b49 100644 --- a/src/mongo/db/mongod_main.cpp +++ b/src/mongo/db/mongod_main.cpp @@ -95,7 +95,6 @@ #include "mongo/db/kill_sessions.h" #include "mongo/db/kill_sessions_local.h" #include "mongo/db/log_process_details.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_session_cache.h" #include "mongo/db/logical_session_cache_factory_mongod.h" #include "mongo/db/logical_time_metadata_hook.h" @@ -969,9 +968,6 @@ void setUpReplication(ServiceContext* serviceContext) { topoCoordOptions.maxSyncSourceLagSecs = Seconds(repl::maxSyncSourceLagSecs); topoCoordOptions.clusterRole = serverGlobalParams.clusterRole; - auto logicalClock = std::make_unique(serviceContext); - LogicalClock::set(serviceContext, std::move(logicalClock)); - auto replCoord = std::make_unique( serviceContext, getGlobalReplSettings(), diff --git a/src/mongo/db/op_msg_fuzzer.cpp b/src/mongo/db/op_msg_fuzzer.cpp index b3dad6a5a17..04810109ef8 100644 --- a/src/mongo/db/op_msg_fuzzer.cpp +++ b/src/mongo/db/op_msg_fuzzer.cpp @@ -33,7 +33,6 @@ #include "mongo/db/auth/authz_manager_external_state_local.h" #include "mongo/db/auth/authz_manager_external_state_mock.h" #include "mongo/db/client.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_time.h" #include "mongo/db/operation_context.h" #include "mongo/db/repl/repl_client_info.h" @@ -98,8 +97,6 @@ extern "C" int LLVMFuzzerTestOneInput(const char* Data, size_t Size) { } mongo::ServiceContext::UniqueOperationContext opCtx = serviceContext->makeOperationContext(client.get()); - auto logicalClock = std::make_unique(serviceContext); - mongo::LogicalClock::set(serviceContext, std::move(logicalClock)); mongo::VectorClockMutable::get(serviceContext)->tickClusterTimeTo(kInMemoryLogicalTime); int new_size = Size + sizeof(int); diff --git a/src/mongo/db/op_observer_impl_test.cpp b/src/mongo/db/op_observer_impl_test.cpp index 51614c4b62e..a802989396c 100644 --- a/src/mongo/db/op_observer_impl_test.cpp +++ b/src/mongo/db/op_observer_impl_test.cpp @@ -35,7 +35,6 @@ #include "mongo/db/dbdirectclient.h" #include "mongo/db/keys_collection_client_sharded.h" #include "mongo/db/keys_collection_manager.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_time_validator.h" #include "mongo/db/op_observer_impl.h" #include "mongo/db/read_write_concern_defaults.h" diff --git a/src/mongo/db/pipeline/document_source_change_stream.cpp b/src/mongo/db/pipeline/document_source_change_stream.cpp index 7a859ccbbd6..b99c8fa6ddb 100644 --- a/src/mongo/db/pipeline/document_source_change_stream.cpp +++ b/src/mongo/db/pipeline/document_source_change_stream.cpp @@ -34,7 +34,6 @@ #include "mongo/bson/simple_bsonelement_comparator.h" #include "mongo/db/bson/bson_helper.h" #include "mongo/db/commands/feature_compatibility_version_documentation.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/pipeline/change_stream_constants.h" #include "mongo/db/pipeline/document_path_support.h" #include "mongo/db/pipeline/document_source_change_stream_close_cursor.h" @@ -52,6 +51,7 @@ #include "mongo/db/repl/oplog_entry.h" #include "mongo/db/repl/oplog_entry_gen.h" #include "mongo/db/repl/replication_coordinator.h" +#include "mongo/db/vector_clock.h" namespace mongo { @@ -413,7 +413,10 @@ list> buildPipeline(const intrusive_ptrinMongos ? LogicalTime{replCoord->getMyLastAppliedOpTime().getTimestamp()} - : LogicalClock::get(expCtx->opCtx)->getClusterTime(); + : [&] { + const auto currentTime = VectorClock::get(expCtx->opCtx)->getTime(); + return currentTime.clusterTime(); + }(); startFrom = currentTime.addTicks(1).asTimestamp(); } diff --git a/src/mongo/db/pipeline/document_source_change_stream_transform.cpp b/src/mongo/db/pipeline/document_source_change_stream_transform.cpp index c42def9ca86..fd12c8822c3 100644 --- a/src/mongo/db/pipeline/document_source_change_stream_transform.cpp +++ b/src/mongo/db/pipeline/document_source_change_stream_transform.cpp @@ -37,7 +37,6 @@ #include "mongo/db/bson/bson_helper.h" #include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/commands/feature_compatibility_version_documentation.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/pipeline/change_stream_constants.h" #include "mongo/db/pipeline/change_stream_document_diff_parser.h" #include "mongo/db/pipeline/document_path_support.h" diff --git a/src/mongo/db/pipeline/expression_context_test.cpp b/src/mongo/db/pipeline/expression_context_test.cpp index ce304716133..294237c0e49 100644 --- a/src/mongo/db/pipeline/expression_context_test.cpp +++ b/src/mongo/db/pipeline/expression_context_test.cpp @@ -30,7 +30,6 @@ #include "mongo/platform/basic.h" #include "mongo/bson/bsonmisc.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_time.h" #include "mongo/db/namespace_string.h" #include "mongo/db/pipeline/expression_context.h" @@ -56,8 +55,6 @@ using ExpressionContextTest = ServiceContextTest; TEST_F(ExpressionContextTest, ExpressionContextSummonsMissingTimeValues) { auto opCtx = makeOperationContext(); - auto logicalClock = std::make_unique(opCtx->getServiceContext()); - LogicalClock::set(opCtx->getServiceContext(), std::move(logicalClock)); auto t1 = VectorClockMutable::get(opCtx->getServiceContext())->tickClusterTime(1); t1.addTicks(100); VectorClockMutable::get(opCtx->getServiceContext())->tickClusterTimeTo(t1); diff --git a/src/mongo/db/pipeline/sharded_agg_helpers.cpp b/src/mongo/db/pipeline/sharded_agg_helpers.cpp index e4275b4a3d9..0639e63ab61 100644 --- a/src/mongo/db/pipeline/sharded_agg_helpers.cpp +++ b/src/mongo/db/pipeline/sharded_agg_helpers.cpp @@ -33,7 +33,6 @@ #include "sharded_agg_helpers.h" #include "mongo/db/curop.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/pipeline/document_source.h" #include "mongo/db/pipeline/document_source_change_stream.h" #include "mongo/db/pipeline/document_source_group.h" @@ -48,6 +47,7 @@ #include "mongo/db/pipeline/document_source_unwind.h" #include "mongo/db/pipeline/lite_parsed_pipeline.h" #include "mongo/db/pipeline/semantic_analysis.h" +#include "mongo/db/vector_clock.h" #include "mongo/logv2/log.h" #include "mongo/rpc/get_status_from_command_result.h" #include "mongo/s/catalog/type_shard.h" @@ -845,7 +845,8 @@ DispatchShardPipelineResults dispatchShardPipeline( // if there was only one shard in the cluster when the command began execution. If a shard was // added since the earlier targeting logic ran, then refreshing here may cause us to illegally // target an unsplit pipeline to more than one shard. - auto shardRegistryReloadTime = LogicalClock::get(opCtx)->getClusterTime().asTimestamp(); + const auto currentTime = VectorClock::get(opCtx)->getTime(); + auto shardRegistryReloadTime = currentTime.clusterTime().asTimestamp(); if (hasChangeStream) { auto* shardRegistry = Grid::get(opCtx)->shardRegistry(); if (!shardRegistry->reload(opCtx)) { diff --git a/src/mongo/db/pipeline/variables.cpp b/src/mongo/db/pipeline/variables.cpp index 28d8e135271..353e3645568 100644 --- a/src/mongo/db/pipeline/variables.cpp +++ b/src/mongo/db/pipeline/variables.cpp @@ -30,9 +30,9 @@ #include "mongo/db/pipeline/variables.h" #include "mongo/bson/bsonobj.h" #include "mongo/db/client.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/pipeline/expression.h" #include "mongo/db/pipeline/variable_validation.h" +#include "mongo/db/vector_clock.h" #include "mongo/platform/basic.h" #include "mongo/platform/random.h" #include "mongo/util/str.h" @@ -224,10 +224,10 @@ RuntimeConstants Variables::generateRuntimeConstants(OperationContext* opCtx) { // logical clock is available, set the clusterTime in the runtime constants. Otherwise, the // clusterTime is set to the null Timestamp. if (opCtx->getClient()) { - if (auto logicalClock = LogicalClock::get(opCtx); logicalClock) { - auto clusterTime = logicalClock->getClusterTime(); - if (clusterTime != LogicalTime::kUninitialized) { - return {Date_t::now(), clusterTime.asTimestamp()}; + if (const auto vectorClock = VectorClock::get(opCtx)) { + const auto now = vectorClock->getTime(); + if (now.clusterTime() != LogicalTime::kUninitialized) { + return {Date_t::now(), now.clusterTime().asTimestamp()}; } } } diff --git a/src/mongo/db/read_concern_mongod.cpp b/src/mongo/db/read_concern_mongod.cpp index 30b76024344..f9eba2ad488 100644 --- a/src/mongo/db/read_concern_mongod.cpp +++ b/src/mongo/db/read_concern_mongod.cpp @@ -34,7 +34,6 @@ #include "mongo/db/catalog_raii.h" #include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/curop_failpoint_helpers.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/op_observer.h" #include "mongo/db/operation_context.h" #include "mongo/db/read_concern.h" @@ -45,6 +44,7 @@ #include "mongo/db/s/sharding_state.h" #include "mongo/db/server_options.h" #include "mongo/db/storage/recovery_unit.h" +#include "mongo/db/vector_clock.h" #include "mongo/logv2/log.h" #include "mongo/s/grid.h" #include "mongo/util/concurrency/notification.h" @@ -334,14 +334,14 @@ Status waitForReadConcernImpl(OperationContext* opCtx, << " readConcern without replication enabled"}; } - auto currentTime = LogicalClock::get(opCtx)->getClusterTime(); - if (currentTime < *targetClusterTime) { + const auto currentTime = VectorClock::get(opCtx)->getTime(); + if (currentTime.clusterTime() < *targetClusterTime) { return {ErrorCodes::InvalidOptions, str::stream() << "readConcern " << readConcernName << " value must not be greater than the current clusterTime. " "Requested clusterTime: " - << targetClusterTime->toString() - << "; current clusterTime: " << currentTime.toString()}; + << targetClusterTime->toString() << "; current clusterTime: " + << currentTime.clusterTime().toString()}; } auto status = makeNoopWriteIfNeeded(opCtx, *targetClusterTime); diff --git a/src/mongo/db/read_write_concern_defaults.cpp b/src/mongo/db/read_write_concern_defaults.cpp index 5e675f6d627..ec9d9cb8625 100644 --- a/src/mongo/db/read_write_concern_defaults.cpp +++ b/src/mongo/db/read_write_concern_defaults.cpp @@ -33,7 +33,7 @@ #include "mongo/db/read_write_concern_defaults.h" -#include "mongo/db/logical_clock.h" +#include "mongo/db/vector_clock.h" #include "mongo/logv2/log.h" namespace mongo { @@ -119,7 +119,8 @@ RWConcernDefault ReadWriteConcernDefaults::generateNewConcerns( } auto* const serviceContext = opCtx->getServiceContext(); - rwc.setUpdateOpTime(LogicalClock::get(serviceContext)->getClusterTime().asTimestamp()); + const auto currentTime = VectorClock::get(serviceContext)->getTime(); + rwc.setUpdateOpTime(currentTime.clusterTime().asTimestamp()); rwc.setUpdateWallClockTime(serviceContext->getFastClockSource()->now()); auto current = _getDefault(opCtx); diff --git a/src/mongo/db/read_write_concern_defaults_test.cpp b/src/mongo/db/read_write_concern_defaults_test.cpp index b17aabda3ad..c07de0e93f0 100644 --- a/src/mongo/db/read_write_concern_defaults_test.cpp +++ b/src/mongo/db/read_write_concern_defaults_test.cpp @@ -29,13 +29,12 @@ #include "mongo/platform/basic.h" -#include "mongo/db/logical_clock.h" -#include "mongo/db/logical_clock_test_fixture.h" #include "mongo/db/read_write_concern_defaults.h" #include "mongo/db/read_write_concern_defaults_cache_lookup_mock.h" #include "mongo/db/repl/optime.h" #include "mongo/db/service_context_test_fixture.h" #include "mongo/db/vector_clock_mutable.h" +#include "mongo/db/vector_clock_test_fixture.h" #include "mongo/util/clock_source_mock.h" namespace mongo { @@ -252,7 +251,7 @@ TEST_F(ReadWriteConcernDefaultsTest, TestRefreshDefaultsWithLowerEpoch) { * ReadWriteConcernDefaults::generateNewConcerns() uses the current clusterTime and wall clock time * (for epoch and setTime/localSetTime), so testing it requires a fixture with a logical clock. */ -class ReadWriteConcernDefaultsTestWithClusterTime : public LogicalClockTestFixture { +class ReadWriteConcernDefaultsTestWithClusterTime : public VectorClockTestFixture { public: virtual ~ReadWriteConcernDefaultsTestWithClusterTime() { _rwcd.invalidate(); diff --git a/src/mongo/db/repair.cpp b/src/mongo/db/repair.cpp index 1ef573f0b45..770b3866dc1 100644 --- a/src/mongo/db/repair.cpp +++ b/src/mongo/db/repair.cpp @@ -52,7 +52,6 @@ #include "mongo/db/db_raii.h" #include "mongo/db/index/index_descriptor.h" #include "mongo/db/index_builds_coordinator.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/namespace_string.h" #include "mongo/db/query/query_knobs_gen.h" #include "mongo/db/rebuild_indexes.h" @@ -61,6 +60,7 @@ #include "mongo/db/storage/storage_engine.h" #include "mongo/db/storage/storage_repair_observer.h" #include "mongo/db/storage/storage_util.h" +#include "mongo/db/vector_clock.h" #include "mongo/logv2/log.h" #include "mongo/util/scopeguard.h" @@ -170,7 +170,7 @@ Status repairDatabase(OperationContext* opCtx, StorageEngine* engine, const std: // Set the minimum snapshot for all Collections in this db. This ensures that readers // using majority readConcern level can only use the collections after their repaired // versions are in the committed view. - auto clusterTime = LogicalClock::getClusterTimeForReplicaSet(opCtx).asTimestamp(); + auto clusterTime = VectorClock::getClusterTimeForReplicaSet(opCtx).asTimestamp(); for (auto collIt = db->begin(opCtx); collIt != db->end(opCtx); ++collIt) { auto collection = diff --git a/src/mongo/db/repl/oplog_fetcher_test.cpp b/src/mongo/db/repl/oplog_fetcher_test.cpp index 5cd3e456eb5..932b7da8e37 100644 --- a/src/mongo/db/repl/oplog_fetcher_test.cpp +++ b/src/mongo/db/repl/oplog_fetcher_test.cpp @@ -29,13 +29,13 @@ #include -#include "mongo/db/logical_clock.h" #include "mongo/db/repl/data_replicator_external_state_mock.h" #include "mongo/db/repl/oplog_fetcher.h" #include "mongo/db/repl/repl_server_parameters_gen.h" #include "mongo/db/repl/task_executor_mock.h" #include "mongo/db/service_context_test_fixture.h" #include "mongo/db/signed_logical_time.h" +#include "mongo/db/vector_clock.h" #include "mongo/dbtests/mock/mock_dbclient_connection.h" #include "mongo/executor/thread_pool_task_executor_test_fixture.h" #include "mongo/rpc/metadata.h" @@ -394,11 +394,6 @@ void OplogFetcherTest::setUp() { // Always enable oplogFetcherUsesExhaust at the beginning of each unittest in case some // unittests disable it in the test. oplogFetcherUsesExhaust = true; - - // Set up a logical clock. - auto service = getGlobalServiceContext(); - auto logicalClock = std::make_unique(service); - LogicalClock::set(service, std::move(logicalClock)); } std::unique_ptr OplogFetcherTest::makeOplogFetcher() { @@ -2284,7 +2279,7 @@ TEST_F(OplogFetcherTest, GetMoreEmptyBatch) { TEST_F(OplogFetcherTest, HandleLogicalTimeMetaDataAndAdvanceClusterTime) { auto firstEntry = makeNoopOplogEntry(lastFetched); - auto oldClusterTime = LogicalClock::get(getGlobalServiceContext())->getClusterTime(); + const auto oldTime = VectorClock::get(getGlobalServiceContext())->getTime(); auto logicalTime = LogicalTime(Timestamp(123456, 78)); auto signedTime = SignedLogicalTime(logicalTime, TimeProofService::TimeProof(), 0); @@ -2309,9 +2304,9 @@ TEST_F(OplogFetcherTest, HandleLogicalTimeMetaDataAndAdvanceClusterTime) { ASSERT_OK(processSingleBatch(makeFirstBatch(0LL, {firstEntry}, metadataObj))->getStatus()); // Test that the cluster time is updated to the cluster time in the metadata. - auto currentClusterTime = LogicalClock::get(getGlobalServiceContext())->getClusterTime(); - ASSERT_EQ(currentClusterTime, logicalTime); - ASSERT_NE(oldClusterTime, logicalTime); + const auto currentTime = VectorClock::get(getGlobalServiceContext())->getTime(); + ASSERT_EQ(currentTime.clusterTime(), logicalTime); + ASSERT_NE(oldTime.clusterTime(), logicalTime); } TEST_F(OplogFetcherTest, CheckFindCommandIncludesFilter) { diff --git a/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp b/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp index 08fe07b0ed2..8e2badd998f 100644 --- a/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp +++ b/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp @@ -56,7 +56,6 @@ #include "mongo/db/index_builds_coordinator.h" #include "mongo/db/jsobj.h" #include "mongo/db/kill_sessions_local.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_time_metadata_hook.h" #include "mongo/db/logical_time_validator.h" #include "mongo/db/op_observer.h" @@ -93,6 +92,7 @@ #include "mongo/db/storage/flow_control.h" #include "mongo/db/storage/storage_engine.h" #include "mongo/db/system_index.h" +#include "mongo/db/vector_clock.h" #include "mongo/executor/network_connection_hook.h" #include "mongo/executor/network_interface.h" #include "mongo/executor/network_interface_factory.h" @@ -710,7 +710,8 @@ void ReplicationCoordinatorExternalStateImpl::setGlobalTimestamp(ServiceContext* } Timestamp ReplicationCoordinatorExternalStateImpl::getGlobalTimestamp(ServiceContext* service) { - return LogicalClock::get(service)->getClusterTime().asTimestamp(); + const auto currentTime = VectorClock::get(service)->getTime(); + return currentTime.clusterTime().asTimestamp(); } bool ReplicationCoordinatorExternalStateImpl::oplogExists(OperationContext* opCtx) { diff --git a/src/mongo/db/repl/replication_coordinator_test_fixture.cpp b/src/mongo/db/repl/replication_coordinator_test_fixture.cpp index 1d34e556e2f..ca22749ea91 100644 --- a/src/mongo/db/repl/replication_coordinator_test_fixture.cpp +++ b/src/mongo/db/repl/replication_coordinator_test_fixture.cpp @@ -36,7 +36,6 @@ #include #include -#include "mongo/db/logical_clock.h" #include "mongo/db/repl/is_master_response.h" #include "mongo/db/repl/repl_set_heartbeat_args_v1.h" #include "mongo/db/repl/repl_settings.h" @@ -129,9 +128,6 @@ void ReplCoordTest::init() { // PRNG seed for tests. const int64_t seed = 0; - auto logicalClock = std::make_unique(service); - LogicalClock::set(service, std::move(logicalClock)); - TopologyCoordinator::Options settings; auto topo = std::make_unique(settings); _topo = topo.get(); diff --git a/src/mongo/db/repl/storage_interface_impl.cpp b/src/mongo/db/repl/storage_interface_impl.cpp index ec13845dce4..f9b6945b259 100644 --- a/src/mongo/db/repl/storage_interface_impl.cpp +++ b/src/mongo/db/repl/storage_interface_impl.cpp @@ -61,7 +61,6 @@ #include "mongo/db/exec/working_set_common.h" #include "mongo/db/jsobj.h" #include "mongo/db/keypattern.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/matcher/extensions_callback_real.h" #include "mongo/db/operation_context.h" #include "mongo/db/ops/delete_request_gen.h" diff --git a/src/mongo/db/s/config/initial_split_policy.cpp b/src/mongo/db/s/config/initial_split_policy.cpp index 36c0f1bf15b..60c719d521d 100644 --- a/src/mongo/db/s/config/initial_split_policy.cpp +++ b/src/mongo/db/s/config/initial_split_policy.cpp @@ -34,8 +34,8 @@ #include "mongo/db/s/config/initial_split_policy.h" #include "mongo/client/read_preference.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/pipeline/sharded_agg_helpers.h" +#include "mongo/db/vector_clock.h" #include "mongo/s/balancer_configuration.h" #include "mongo/s/catalog/type_shard.h" #include "mongo/s/grid.h" @@ -273,11 +273,12 @@ InitialSplitPolicy::ShardCollectionConfig SingleChunkOnPrimarySplitPolicy::creat ShardCollectionConfig initialChunks; ChunkVersion version(1, 0, OID::gen()); const auto& keyPattern = shardKeyPattern.getKeyPattern(); + const auto currentTime = VectorClock::get(opCtx)->getTime(); appendChunk(params.nss, keyPattern.globalMin(), keyPattern.globalMax(), &version, - LogicalClock::get(opCtx)->getClusterTime().asTimestamp(), + currentTime.clusterTime().asTimestamp(), params.primaryShardId, &initialChunks.chunks); return initialChunks; @@ -301,14 +302,14 @@ InitialSplitPolicy::ShardCollectionConfig UnoptimizedSplitPolicy::createFirstChu shardKeyPattern.getKeyPattern().globalMax()), balancerConfig->getMaxChunkSizeBytes(), 0)); - return generateShardCollectionInitialChunks( - params.nss, - shardKeyPattern, - params.primaryShardId, - LogicalClock::get(opCtx)->getClusterTime().asTimestamp(), - shardSelectedSplitPoints, - shardIds, - 1 // numContiguousChunksPerShard + const auto currentTime = VectorClock::get(opCtx)->getTime(); + return generateShardCollectionInitialChunks(params.nss, + shardKeyPattern, + params.primaryShardId, + currentTime.clusterTime().asTimestamp(), + shardSelectedSplitPoints, + shardIds, + 1 // numContiguousChunksPerShard ); } @@ -321,14 +322,14 @@ InitialSplitPolicy::ShardCollectionConfig SplitPointsBasedSplitPolicy::createFir std::vector shardIds; shardRegistry->getAllShardIdsNoReload(&shardIds); - return generateShardCollectionInitialChunks( - params.nss, - shardKeyPattern, - params.primaryShardId, - LogicalClock::get(opCtx)->getClusterTime().asTimestamp(), - _splitPoints, - shardIds, - _numContiguousChunksPerShard); + const auto currentTime = VectorClock::get(opCtx)->getTime(); + return generateShardCollectionInitialChunks(params.nss, + shardKeyPattern, + params.primaryShardId, + currentTime.clusterTime().asTimestamp(), + _splitPoints, + shardIds, + _numContiguousChunksPerShard); } AbstractTagsBasedSplitPolicy::AbstractTagsBasedSplitPolicy(OperationContext* opCtx, @@ -356,7 +357,8 @@ InitialSplitPolicy::ShardCollectionConfig AbstractTagsBasedSplitPolicy::createFi std::vector shardIds; shardRegistry->getAllShardIdsNoReload(&shardIds); - const auto validAfter = LogicalClock::get(opCtx)->getClusterTime().asTimestamp(); + const auto currentTime = VectorClock::get(opCtx)->getTime(); + const auto validAfter = currentTime.clusterTime().asTimestamp(); const auto& keyPattern = shardKeyPattern.getKeyPattern(); auto tagToShards = getTagsToShardIds(); @@ -667,12 +669,13 @@ ReshardingSplitPolicy::ReshardingSplitPolicy(OperationContext* opCtx, InitialSplitPolicy::ShardCollectionConfig ReshardingSplitPolicy::createFirstChunks( OperationContext* opCtx, const ShardKeyPattern& shardKeyPattern, SplitPolicyParams params) { + const auto currentTime = VectorClock::get(opCtx)->getTime(); return createChunks(shardKeyPattern, params, _numContiguousChunksPerShard, _recipientShardIds, _splitPoints, - LogicalClock::get(opCtx)->getClusterTime().asTimestamp()); + currentTime.clusterTime().asTimestamp()); } } // namespace mongo diff --git a/src/mongo/db/s/config/initial_split_policy_test.cpp b/src/mongo/db/s/config/initial_split_policy_test.cpp index a8702c81606..b974830f7f5 100644 --- a/src/mongo/db/s/config/initial_split_policy_test.cpp +++ b/src/mongo/db/s/config/initial_split_policy_test.cpp @@ -32,9 +32,9 @@ #include "mongo/platform/basic.h" #include "mongo/bson/json.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/s/config/config_server_test_fixture.h" #include "mongo/db/s/config/initial_split_policy.h" +#include "mongo/db/vector_clock.h" #include "mongo/s/catalog/type_shard.h" #include "mongo/s/catalog/type_tags.h" #include "mongo/unittest/unittest.h" @@ -331,10 +331,9 @@ public: const auto shardCollectionConfig = splitPolicy.createFirstChunks(opCtx, shardKeyPattern, {}); - const std::vector expectedChunks = - makeChunks(expectedChunkRanges, - expectedShardIds, - LogicalClock::get(opCtx)->getClusterTime().asTimestamp()); + const auto currentTime = VectorClock::get(opCtx)->getTime(); + const std::vector expectedChunks = makeChunks( + expectedChunkRanges, expectedShardIds, currentTime.clusterTime().asTimestamp()); assertChunkVectorsAreEqual(expectedChunks, shardCollectionConfig.chunks); } @@ -582,10 +581,9 @@ public: const auto shardCollectionConfig = splitPolicy.createFirstChunks(operationContext(), shardKeyPattern, {}); - const std::vector expectedChunks = - makeChunks(expectedChunkRanges, - expectedShardIds, - LogicalClock::get(operationContext())->getClusterTime().asTimestamp()); + const auto currentTime = VectorClock::get(operationContext())->getTime(); + const std::vector expectedChunks = makeChunks( + expectedChunkRanges, expectedShardIds, currentTime.clusterTime().asTimestamp()); assertChunkVectorsAreEqual(expectedChunks, shardCollectionConfig.chunks); } }; diff --git a/src/mongo/db/s/config/sharding_catalog_manager_collection_operations.cpp b/src/mongo/db/s/config/sharding_catalog_manager_collection_operations.cpp index 01aedaceb5e..23b6688bf9e 100644 --- a/src/mongo/db/s/config/sharding_catalog_manager_collection_operations.cpp +++ b/src/mongo/db/s/config/sharding_catalog_manager_collection_operations.cpp @@ -48,7 +48,6 @@ #include "mongo/db/catalog/collection_options.h" #include "mongo/db/client.h" #include "mongo/db/commands.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_session_cache.h" #include "mongo/db/namespace_string.h" #include "mongo/db/operation_context.h" diff --git a/src/mongo/db/s/merge_chunks_command.cpp b/src/mongo/db/s/merge_chunks_command.cpp index 7dd1cb1f20d..0eb7a19ac65 100644 --- a/src/mongo/db/s/merge_chunks_command.cpp +++ b/src/mongo/db/s/merge_chunks_command.cpp @@ -37,11 +37,11 @@ #include "mongo/db/catalog_raii.h" #include "mongo/db/commands.h" #include "mongo/db/field_parser.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/namespace_string.h" #include "mongo/db/s/collection_sharding_runtime.h" #include "mongo/db/s/shard_filtering_metadata_refresh.h" #include "mongo/db/s/sharding_state.h" +#include "mongo/db/vector_clock.h" #include "mongo/logv2/log.h" #include "mongo/s/catalog/type_chunk.h" #include "mongo/s/client/shard_registry.h" @@ -196,11 +196,12 @@ void mergeChunks(OperationContext* opCtx, // // Run _configsvrCommitChunkMerge. // + const auto currentTime = VectorClock::get(opCtx)->getTime(); MergeChunkRequest request{nss, shardingState->shardId().toString(), epoch, chunkBoundaries, - LogicalClock::get(opCtx)->getClusterTime().asTimestamp()}; + currentTime.clusterTime().asTimestamp()}; auto configCmdObj = request.toConfigCommandBSON(ShardingCatalogClient::kMajorityWriteConcern.toBSON()); diff --git a/src/mongo/db/s/migration_source_manager.cpp b/src/mongo/db/s/migration_source_manager.cpp index 07f8f94daf9..caca00e850f 100644 --- a/src/mongo/db/s/migration_source_manager.cpp +++ b/src/mongo/db/s/migration_source_manager.cpp @@ -36,7 +36,6 @@ #include "mongo/bson/bsonobjbuilder.h" #include "mongo/db/catalog_raii.h" #include "mongo/db/concurrency/write_conflict_exception.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_session_cache.h" #include "mongo/db/logical_session_id_helpers.h" #include "mongo/db/op_observer.h" @@ -53,6 +52,7 @@ #include "mongo/db/s/sharding_state.h" #include "mongo/db/s/sharding_state_recovery.h" #include "mongo/db/s/sharding_statistics.h" +#include "mongo/db/vector_clock.h" #include "mongo/executor/task_executor.h" #include "mongo/executor/task_executor_pool.h" #include "mongo/logv2/log.h" @@ -408,14 +408,14 @@ Status MigrationSourceManager::commitChunkMetadataOnConfig() { migratedChunkType.setMax(_args.getMaxKey()); migratedChunkType.setVersion(_chunkVersion); - CommitChunkMigrationRequest::appendAsCommand( - &builder, - getNss(), - _args.getFromShardId(), - _args.getToShardId(), - migratedChunkType, - metadata.getCollVersion(), - LogicalClock::get(_opCtx)->getClusterTime().asTimestamp()); + const auto currentTime = VectorClock::get(_opCtx)->getTime(); + CommitChunkMigrationRequest::appendAsCommand(&builder, + getNss(), + _args.getFromShardId(), + _args.getToShardId(), + migratedChunkType, + metadata.getCollVersion(), + currentTime.clusterTime().asTimestamp()); builder.append(kWriteConcernField, kMajorityWriteConcern.toBSON()); } diff --git a/src/mongo/db/s/shardsvr_shard_collection.cpp b/src/mongo/db/s/shardsvr_shard_collection.cpp index 7488d687790..a311110cc98 100644 --- a/src/mongo/db/s/shardsvr_shard_collection.cpp +++ b/src/mongo/db/s/shardsvr_shard_collection.cpp @@ -41,7 +41,6 @@ #include "mongo/db/dbdirectclient.h" #include "mongo/db/hasher.h" #include "mongo/db/index/index_descriptor.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/namespace_string.h" #include "mongo/db/query/collation/collator_factory_interface.h" #include "mongo/db/s/active_shard_collection_registry.h" diff --git a/src/mongo/db/service_context_d_test_fixture.cpp b/src/mongo/db/service_context_d_test_fixture.cpp index 08192fd53fb..9c23bcbabda 100644 --- a/src/mongo/db/service_context_d_test_fixture.cpp +++ b/src/mongo/db/service_context_d_test_fixture.cpp @@ -43,7 +43,6 @@ #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/index/index_access_method_factory_impl.h" #include "mongo/db/index_builds_coordinator_mongod.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/op_observer_registry.h" #include "mongo/db/s/collection_sharding_state_factory_shard.h" #include "mongo/db/service_entry_point_mongod.h" @@ -83,8 +82,6 @@ ServiceContextMongoDTest::ServiceContextMongoDTest(std::string engine, RepairAct auto const serviceContext = getServiceContext(); serviceContext->setServiceEntryPoint(std::make_unique(serviceContext)); - auto logicalClock = std::make_unique(serviceContext); - LogicalClock::set(serviceContext, std::move(logicalClock)); // Set up the periodic runner to allow background job execution for tests that require it. auto runner = makePeriodicRunner(getServiceContext()); diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp index 77dda9f44a5..b9210ccc995 100644 --- a/src/mongo/db/service_entry_point_common.cpp +++ b/src/mongo/db/service_entry_point_common.cpp @@ -57,7 +57,6 @@ #include "mongo/db/introspect.h" #include "mongo/db/jsobj.h" #include "mongo/db/lasterror.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_session_id.h" #include "mongo/db/logical_session_id_helpers.h" #include "mongo/db/logical_time_validator.h" diff --git a/src/mongo/db/service_liaison.cpp b/src/mongo/db/service_liaison.cpp index 85d2acbd39a..8f370ccd1bc 100644 --- a/src/mongo/db/service_liaison.cpp +++ b/src/mongo/db/service_liaison.cpp @@ -31,7 +31,6 @@ #include "mongo/db/service_liaison.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/service_context.h" namespace mongo { diff --git a/src/mongo/db/storage/storage_engine_impl.cpp b/src/mongo/db/storage/storage_engine_impl.cpp index 22c82a09eba..cf4d17f3f1d 100644 --- a/src/mongo/db/storage/storage_engine_impl.cpp +++ b/src/mongo/db/storage/storage_engine_impl.cpp @@ -39,7 +39,6 @@ #include "mongo/db/client.h" #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/index_builds_coordinator.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/operation_context_noop.h" #include "mongo/db/server_options.h" #include "mongo/db/storage/durable_catalog_feature_tracker.h" diff --git a/src/mongo/db/update/object_replace_executor_test.cpp b/src/mongo/db/update/object_replace_executor_test.cpp index 0f7adf40df5..811c8eb0e06 100644 --- a/src/mongo/db/update/object_replace_executor_test.cpp +++ b/src/mongo/db/update/object_replace_executor_test.cpp @@ -34,7 +34,6 @@ #include "mongo/bson/mutable/algorithm.h" #include "mongo/bson/mutable/mutable_bson_test_utils.h" #include "mongo/db/json.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/update/update_node_test_fixture.h" #include "mongo/unittest/unittest.h" diff --git a/src/mongo/db/update/pipeline_executor_test.cpp b/src/mongo/db/update/pipeline_executor_test.cpp index e1dfaf40fd8..496b99ef3ce 100644 --- a/src/mongo/db/update/pipeline_executor_test.cpp +++ b/src/mongo/db/update/pipeline_executor_test.cpp @@ -35,7 +35,6 @@ #include "mongo/bson/mutable/mutable_bson_test_utils.h" #include "mongo/db/exec/document_value/document_value_test_util.h" #include "mongo/db/json.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/pipeline/expression_context_for_test.h" #include "mongo/db/query/query_knobs_gen.h" #include "mongo/db/update/update_node_test_fixture.h" diff --git a/src/mongo/db/update/update_node_test_fixture.h b/src/mongo/db/update/update_node_test_fixture.h index aaa72fe2545..b9c27ed8bc0 100644 --- a/src/mongo/db/update/update_node_test_fixture.h +++ b/src/mongo/db/update/update_node_test_fixture.h @@ -29,7 +29,6 @@ #pragma once -#include "mongo/db/logical_clock.h" #include "mongo/db/service_context.h" #include "mongo/db/service_context_test_fixture.h" #include "mongo/db/update/update_node.h" @@ -69,11 +68,6 @@ protected: void setUp() override { resetApplyParams(); - - // Set up the logical clock needed by CurrentDateNode and ObjectReplaceExecutor. - auto service = mongo::getGlobalServiceContext(); - auto logicalClock = std::make_unique(service); - mongo::LogicalClock::set(service, std::move(logicalClock)); } virtual void resetApplyParams() { diff --git a/src/mongo/db/vector_clock.cpp b/src/mongo/db/vector_clock.cpp index ba65d0acaa9..abbc490d586 100644 --- a/src/mongo/db/vector_clock.cpp +++ b/src/mongo/db/vector_clock.cpp @@ -33,6 +33,7 @@ #include "mongo/bson/util/bson_extract.h" #include "mongo/db/auth/authorization_session.h" +#include "mongo/db/global_settings.h" #include "mongo/db/logical_clock_gen.h" #include "mongo/db/logical_time_validator.h" #include "mongo/db/vector_clock_document_gen.h" @@ -79,6 +80,18 @@ VectorClock::VectorTime VectorClock::getTime() const { return VectorTime(_vectorTime); } +LogicalTime VectorClock::getClusterTimeForReplicaSet(ServiceContext* svcCtx) { + if (getGlobalReplSettings().usingReplSets()) { + auto now = get(svcCtx)->getTime(); + return now.clusterTime(); + } + return {}; +} + +LogicalTime VectorClock::getClusterTimeForReplicaSet(OperationContext* opCtx) { + return getClusterTimeForReplicaSet(opCtx->getClient()->getServiceContext()); +} + bool VectorClock::_lessThanOrEqualToMaxPossibleTime(LogicalTime time, uint64_t nTicks) { return time.asTimestamp().getSecs() <= kMaxValue && time.asTimestamp().getInc() <= (kMaxValue - nTicks); diff --git a/src/mongo/db/vector_clock.h b/src/mongo/db/vector_clock.h index 9cf544a06c0..b33151f3a3e 100644 --- a/src/mongo/db/vector_clock.h +++ b/src/mongo/db/vector_clock.h @@ -135,6 +135,13 @@ public: */ VectorTime getTime() const; + /** + * Returns the current cluster time if this is a replica set node, otherwise returns a null + * logical time. + */ + static LogicalTime getClusterTimeForReplicaSet(ServiceContext* svcCtx); + static LogicalTime getClusterTimeForReplicaSet(OperationContext* opCtx); + /** * Adds the necessary fields to outMessage to gossip the current time to another node, taking * into account if the gossiping is to an internal or external client (based on the session diff --git a/src/mongo/db/vector_clock_test.cpp b/src/mongo/db/vector_clock_test.cpp new file mode 100644 index 00000000000..b889f463e7d --- /dev/null +++ b/src/mongo/db/vector_clock_test.cpp @@ -0,0 +1,335 @@ +/** + * Copyright (C) 2018-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * 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 + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + * + * 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 Server Side 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_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kTest + +#include "mongo/platform/basic.h" + +#include + +#include "mongo/bson/bsonobj.h" +#include "mongo/bson/timestamp.h" +#include "mongo/db/dbdirectclient.h" +#include "mongo/db/logical_clock_gen.h" +#include "mongo/db/logical_time.h" +#include "mongo/db/repl/replication_coordinator_mock.h" +#include "mongo/db/vector_clock_mutable.h" +#include "mongo/db/vector_clock_test_fixture.h" +#include "mongo/unittest/unittest.h" +#include "mongo/util/clock_source_mock.h" + +namespace mongo { +namespace { + +const NamespaceString kDummyNamespaceString("test", "foo"); + +using VectorClockTest = VectorClockTestFixture; + +constexpr unsigned maxVal = std::numeric_limits::max(); + +LogicalTime buildLogicalTime(unsigned secs, unsigned inc) { + return LogicalTime(Timestamp(secs, inc)); +} + +// Check that the initial time does not change during VectorClock creation. +TEST_F(VectorClockTest, roundtrip) { + Timestamp tX(1); + auto time = LogicalTime(tX); + + VectorClockMutable::get(getServiceContext())->tickClusterTimeTo(time); + auto storedTime(getClusterTime()); + + ASSERT_TRUE(storedTime == time); +} + +// Verify the reserve ticks functionality. +TEST_F(VectorClockTest, reserveTicks) { + // Set clock to a non-zero time, so we can verify wall clock synchronization. + setMockClockSourceTime(Date_t::fromMillisSinceEpoch(10 * 1000)); + + auto t1 = VectorClockMutable::get(getServiceContext())->tickClusterTime(1); + auto t2(getClusterTime()); + ASSERT_TRUE(t1 == t2); + + // Make sure we synchronized with the wall clock. + ASSERT_TRUE(t2.asTimestamp().getSecs() == 10); + + auto t3 = VectorClockMutable::get(getServiceContext())->tickClusterTime(1); + t1.addTicks(1); + ASSERT_TRUE(t3 == t1); + + t3 = VectorClockMutable::get(getServiceContext())->tickClusterTime(100); + t1.addTicks(1); + ASSERT_TRUE(t3 == t1); + + t3 = VectorClockMutable::get(getServiceContext())->tickClusterTime(1); + t1.addTicks(100); + ASSERT_TRUE(t3 == t1); + + // Ensure overflow to a new second. + auto initTimeSecs = getClusterTime().asTimestamp().getSecs(); + VectorClockMutable::get(getServiceContext())->tickClusterTime((1U << 31) - 1); + auto newTimeSecs = getClusterTime().asTimestamp().getSecs(); + ASSERT_TRUE(newTimeSecs == initTimeSecs + 1); +} + +// Verify the advanceClusterTime functionality. +TEST_F(VectorClockTest, advanceClusterTime) { + auto t1 = VectorClockMutable::get(getServiceContext())->tickClusterTime(1); + t1.addTicks(100); + advanceClusterTime(t1); + ASSERT_TRUE(t1 == getClusterTime()); +} + +// Verify rate limiter rejects cluster times whose seconds values are too far ahead. +TEST_F(VectorClockTest, RateLimiterRejectsLogicalTimesTooFarAhead) { + setMockClockSourceTime(Date_t::fromMillisSinceEpoch(10 * 1000)); + + Timestamp tooFarAheadTimestamp( + durationCount(getMockClockSourceTime().toDurationSinceEpoch()) + + kMaxAcceptableLogicalClockDriftSecsDefault + + 10, // Add 10 seconds to ensure limit is exceeded. + 1); + LogicalTime t1(tooFarAheadTimestamp); + + ASSERT_THROWS_CODE( + advanceClusterTime(t1), DBException, ErrorCodes::ClusterTimeFailsRateLimiter); +} + +// Verify cluster time can be initialized to a very old time. +TEST_F(VectorClockTest, InitFromTrustedSourceCanAcceptVeryOldLogicalTime) { + setMockClockSourceTime(Date_t::fromMillisSinceEpoch( + durationCount(Seconds(kMaxAcceptableLogicalClockDriftSecsDefault)) * 10 * 1000)); + + Timestamp veryOldTimestamp( + durationCount(getMockClockSourceTime().toDurationSinceEpoch()) - + (kMaxAcceptableLogicalClockDriftSecsDefault * 5)); + auto veryOldTime = LogicalTime(veryOldTimestamp); + VectorClockMutable::get(getServiceContext())->tickClusterTimeTo(veryOldTime); + + ASSERT_TRUE(getClusterTime() == veryOldTime); +} + +// Verify writes to the oplog advance cluster time. +TEST_F(VectorClockTest, WritesToOplogAdvanceClusterTime) { + Timestamp tX(1, 0); + auto initialTime = LogicalTime(tX); + + VectorClockMutable::get(getServiceContext())->tickClusterTimeTo(initialTime); + ASSERT_TRUE(getClusterTime() == initialTime); + + getDBClient()->insert(kDummyNamespaceString.ns(), BSON("x" << 1)); + ASSERT_TRUE(getClusterTime() > initialTime); + ASSERT_EQ(getClusterTime().asTimestamp(), + replicationCoordinator()->getMyLastAppliedOpTime().getTimestamp()); +} + +// Tests the scenario where an admin incorrectly sets the wall clock more than +// maxAcceptableLogicalClockDriftSecs in the past at startup, and cluster time is initialized to +// the incorrect past time, then the admin resets the clock to the current time. In this case, +// cluster time can be advanced through metadata as long as the new time isn't +// maxAcceptableLogicalClockDriftSecs ahead of the correct current wall clock time, since the rate +// limiter compares new times to the wall clock, not the cluster time. +TEST_F(VectorClockTest, WallClockSetTooFarInPast) { + auto oneDay = Seconds(24 * 60 * 60); + + // Current wall clock and cluster time. + auto currentSecs = Seconds(kMaxAcceptableLogicalClockDriftSecsDefault) * 10; + LogicalTime currentTime(Timestamp(currentSecs, 0)); + + // Set wall clock more than maxAcceptableLogicalClockDriftSecs seconds in the past. + auto pastSecs = currentSecs - Seconds(kMaxAcceptableLogicalClockDriftSecsDefault) - oneDay; + setMockClockSourceTime(Date_t::fromDurationSinceEpoch(pastSecs)); + + // If cluster time is either uninitialized or even farther in the past, a write would set + // cluster time more than maxAcceptableLogicalClockDriftSecs in the past. + getDBClient()->insert(kDummyNamespaceString.ns(), BSON("x" << 1)); + ASSERT_TRUE(getClusterTime() < + LogicalTime(Timestamp( + currentSecs - Seconds(kMaxAcceptableLogicalClockDriftSecsDefault), 0))); + + // Set wall clock to the current time on the affected node. + setMockClockSourceTime(Date_t::fromDurationSinceEpoch(currentSecs)); + + // Verify that maxAcceptableLogicalClockDriftSecs parameter does not need to be increased to + // advance cluster time through metadata back to the current time. + advanceClusterTime(currentTime); + ASSERT_TRUE(getClusterTime() == currentTime); +} + +// Tests the scenario where an admin incorrectly sets the wall clock more than +// maxAcceptableLogicalClockDriftSecs in the future and a write is accepted, advancing cluster +// time, then the admin resets the clock to the current time. In this case, cluster time cannot be +// advanced through metadata unless the drift parameter is increased. +TEST_F(VectorClockTest, WallClockSetTooFarInFuture) { + auto oneDay = Seconds(24 * 60 * 60); + + // Current wall clock and cluster time. + auto currentSecs = Seconds(kMaxAcceptableLogicalClockDriftSecsDefault) * 10; + LogicalTime currentTime(Timestamp(currentSecs, 0)); + + // Set wall clock more than maxAcceptableLogicalClockDriftSecs seconds in the future. + auto futureSecs = currentSecs + Seconds(kMaxAcceptableLogicalClockDriftSecsDefault) + oneDay; + setMockClockSourceTime(Date_t::fromDurationSinceEpoch(futureSecs)); + + // A write gets through and advances cluster time more than maxAcceptableLogicalClockDriftSecs + // in the future. + getDBClient()->insert(kDummyNamespaceString.ns(), BSON("x" << 1)); + ASSERT_TRUE(getClusterTime() > + LogicalTime(Timestamp( + currentSecs + Seconds(kMaxAcceptableLogicalClockDriftSecsDefault), 0))); + + // Set wall clock to the current time on the affected node. + setMockClockSourceTime(Date_t::fromDurationSinceEpoch(currentSecs)); + + // Verify that maxAcceptableLogicalClockDriftSecs parameter has to be increased to advance + // cluster time through metadata. + auto nextTime = getClusterTime(); + nextTime.addTicks(1); // The next lowest cluster time. + + ASSERT_THROWS_CODE( + advanceClusterTime(nextTime), DBException, ErrorCodes::ClusterTimeFailsRateLimiter); + + // Set wall clock to the current time + 1 day to simulate increasing the + // maxAcceptableLogicalClockDriftSecs parameter, which can only be set at startup, and verify + // time can be advanced through metadata again. + setMockClockSourceTime(Date_t::fromDurationSinceEpoch(currentSecs + oneDay)); + + advanceClusterTime(nextTime); + ASSERT_TRUE(getClusterTime() == nextTime); +} + +// Verify the behavior of advancing cluster time around the max allowed values. +TEST_F(VectorClockTest, ReserveTicksBehaviorAroundMaxTime) { + // Verify clock can be advanced near the max values. + + // Can always advance to the max value for the inc field. + resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal - 1, maxVal - 1)); + VectorClockMutable::get(getServiceContext())->tickClusterTime(1); + ASSERT_EQ(getClusterTime(), buildLogicalTime(maxVal - 1, maxVal)); + + resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal - 1, maxVal - 5)); + VectorClockMutable::get(getServiceContext())->tickClusterTime(5); + ASSERT_EQ(getClusterTime(), buildLogicalTime(maxVal - 1, maxVal)); + + resetClock()->tickClusterTimeTo(buildLogicalTime(0, maxVal - 1)); + VectorClockMutable::get(getServiceContext())->tickClusterTime(1); + ASSERT_EQ(getClusterTime(), buildLogicalTime(0, maxVal)); + + // Can overflow inc into seconds to reach max seconds value. + resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal - 1, maxVal)); + VectorClockMutable::get(getServiceContext())->tickClusterTime(1); + ASSERT_EQ(getClusterTime(), buildLogicalTime(maxVal, 1)); + + resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal - 1, maxVal - 5)); + VectorClockMutable::get(getServiceContext())->tickClusterTime(10); + ASSERT_EQ(getClusterTime(), buildLogicalTime(maxVal, 10)); + + resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal - 1, 1)); + VectorClockMutable::get(getServiceContext())->tickClusterTime(maxVal); + ASSERT_EQ(getClusterTime(), buildLogicalTime(maxVal, maxVal)); + + // Can advance inc field when seconds field is at the max value. + resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal, 1)); + VectorClockMutable::get(getServiceContext())->tickClusterTime(1); + ASSERT_EQ(getClusterTime(), buildLogicalTime(maxVal, 2)); + + resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal, 1)); + VectorClockMutable::get(getServiceContext())->tickClusterTime(100); + ASSERT_EQ(getClusterTime(), buildLogicalTime(maxVal, 101)); + + // Can advance to the max value for both the inc and seconds fields. + resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal, maxVal - 1)); + VectorClockMutable::get(getServiceContext())->tickClusterTime(1); + ASSERT_EQ(getClusterTime(), buildLogicalTime(maxVal, maxVal)); + + resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal, maxVal - 5)); + VectorClockMutable::get(getServiceContext())->tickClusterTime(5); + ASSERT_EQ(getClusterTime(), buildLogicalTime(maxVal, maxVal)); + + // Verify scenarios where the clock cannot be advanced. + + // Can't overflow inc into seconds when seconds field is at the max value. + resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal, maxVal)); + ASSERT_THROWS(VectorClockMutable::get(getServiceContext())->tickClusterTime(1), DBException); + ASSERT_EQ(getClusterTime(), buildLogicalTime(maxVal, maxVal)); + + resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal, maxVal)); + ASSERT_THROWS(VectorClockMutable::get(getServiceContext())->tickClusterTime(5), DBException); + ASSERT_EQ(getClusterTime(), buildLogicalTime(maxVal, maxVal)); + + resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal, maxVal - 1)); + ASSERT_THROWS(VectorClockMutable::get(getServiceContext())->tickClusterTime(2), DBException); + ASSERT_EQ(getClusterTime(), buildLogicalTime(maxVal, maxVal - 1)); + + resetClock()->tickClusterTimeTo(buildLogicalTime(maxVal, maxVal - 11)); + ASSERT_THROWS(VectorClockMutable::get(getServiceContext())->tickClusterTime(12), DBException); + ASSERT_EQ(getClusterTime(), buildLogicalTime(maxVal, maxVal - 11)); +} + +// Verify behavior of advancing cluster time when the wall clock is near the max allowed value. +TEST_F(VectorClockTest, ReserveTicksBehaviorWhenWallClockNearMaxTime) { + // Can be set to the max possible time by catching up to the wall clock. + setMockClockSourceTime(Date_t::fromDurationSinceEpoch(Seconds(maxVal))); + + resetClock()->tickClusterTimeTo(buildLogicalTime(1, 1)); + VectorClockMutable::get(getServiceContext())->tickClusterTime(1); + ASSERT_EQ(getClusterTime(), buildLogicalTime(maxVal, 1)); + + // Should fail when wall clock would advance cluster time beyond the max allowed time. + setMockClockSourceTime(Date_t::max()); + + resetClock()->tickClusterTimeTo(buildLogicalTime(1, 1)); + ASSERT_THROWS(VectorClockMutable::get(getServiceContext())->tickClusterTime(1), DBException); + ASSERT_EQ(getClusterTime(), buildLogicalTime(1, 1)); +} + +// Verify the clock rejects cluster times greater than the max allowed time. +TEST_F(VectorClockTest, RejectsLogicalTimesGreaterThanMaxTime) { + // A cluster time can be greater than the maximum value allowed because the signed integer + // maximum is used for legacy compatibility, but these fields are stored as unsigned integers. + auto beyondMaxTime = buildLogicalTime(maxVal + 1, maxVal + 1); + + // The clock can't be initialized to a time greater than the max possible. + resetClock(); + ASSERT_THROWS(VectorClockMutable::get(getServiceContext())->tickClusterTimeTo(beyondMaxTime), + DBException); + ASSERT_TRUE(getClusterTime() == LogicalTime()); + + // The time can't be advanced through metadata to a time greater than the max possible. + // Advance the wall clock close enough to the new value so the rate check is passed. + auto almostMaxSecs = + Seconds(maxVal) - Seconds(kMaxAcceptableLogicalClockDriftSecsDefault) + Seconds(10); + setMockClockSourceTime(Date_t::fromDurationSinceEpoch(almostMaxSecs)); + ASSERT_THROWS(advanceClusterTime(beyondMaxTime), DBException); + ASSERT_TRUE(getClusterTime() == LogicalTime()); +} + +} // unnamed namespace +} // namespace mongo diff --git a/src/mongo/db/vector_clock_test_fixture.cpp b/src/mongo/db/vector_clock_test_fixture.cpp new file mode 100644 index 00000000000..b8c7205512e --- /dev/null +++ b/src/mongo/db/vector_clock_test_fixture.cpp @@ -0,0 +1,107 @@ +/** + * Copyright (C) 2018-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * 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 + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + * + * 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 Server Side 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/vector_clock_test_fixture.h" + +#include + +#include "mongo/db/dbdirectclient.h" +#include "mongo/db/logical_time.h" +#include "mongo/db/repl/replication_coordinator_mock.h" +#include "mongo/db/service_context.h" +#include "mongo/db/signed_logical_time.h" +#include "mongo/db/time_proof_service.h" +#include "mongo/db/vector_clock_mutable.h" +#include "mongo/unittest/unittest.h" +#include "mongo/util/clock_source_mock.h" + +namespace mongo { + +VectorClockTestFixture::VectorClockTestFixture() = default; + +VectorClockTestFixture::~VectorClockTestFixture() = default; + +void VectorClockTestFixture::setUp() { + ShardingMongodTestFixture::setUp(); + + auto service = getServiceContext(); + + _clock = VectorClock::get(service); + + service->setFastClockSource(std::make_unique(_mockClockSource)); + service->setPreciseClockSource(std::make_unique(_mockClockSource)); + + _dbDirectClient = std::make_unique(operationContext()); + + ASSERT_OK(replicationCoordinator()->setFollowerMode(repl::MemberState::RS_PRIMARY)); +} + +void VectorClockTestFixture::tearDown() { + _dbDirectClient.reset(); + ShardingMongodTestFixture::tearDown(); +} + +VectorClockMutable* VectorClockTestFixture::resetClock() { + auto service = getServiceContext(); + VectorClock::get(service)->resetVectorClock_forTest(); + return VectorClockMutable::get(service); +} + +void VectorClockTestFixture::advanceClusterTime(LogicalTime newTime) { + VectorClock::get(getServiceContext())->advanceClusterTime_forTest(newTime); +} + +VectorClock* VectorClockTestFixture::getClock() const { + return _clock; +} + +LogicalTime VectorClockTestFixture::getClusterTime() const { + auto now = getClock()->getTime(); + return now.clusterTime(); +} + +ClockSourceMock* VectorClockTestFixture::getMockClockSource() const { + return _mockClockSource.get(); +} + +void VectorClockTestFixture::setMockClockSourceTime(Date_t time) const { + _mockClockSource->reset(time); +} + +Date_t VectorClockTestFixture::getMockClockSourceTime() const { + return _mockClockSource->now(); +} + +DBDirectClient* VectorClockTestFixture::getDBClient() const { + return _dbDirectClient.get(); +} + +} // namespace mongo diff --git a/src/mongo/db/vector_clock_test_fixture.h b/src/mongo/db/vector_clock_test_fixture.h new file mode 100644 index 00000000000..96a3a94a577 --- /dev/null +++ b/src/mongo/db/vector_clock_test_fixture.h @@ -0,0 +1,83 @@ +/** + * Copyright (C) 2018-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * 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 + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + * + * 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 Server Side 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. + */ + +#pragma once + +#include "mongo/db/s/sharding_mongod_test_fixture.h" + +namespace mongo { + +class ClockSourceMock; +class DBDirectClient; +class LogicalTime; +class VectorClock; +class VectorClockMutable; + +/** + * A test fixture that installs a VectorClock instance with a TimeProofService onto a service + * context, in addition to the mock storage engine, network, and OpObserver provided by + * ShardingMongodTestFixture. + */ +class VectorClockTestFixture : public ShardingMongodTestFixture { +public: + VectorClockTestFixture(); + ~VectorClockTestFixture(); + +protected: + /** + * Sets up this fixture as the primary node in a shard server replica set with a VectorClock + * (with a TimeProofService), storage engine, DBClient, OpObserver, and a mocked clock source. + */ + void setUp() override; + + void tearDown() override; + + VectorClockMutable* resetClock(); + + void advanceClusterTime(LogicalTime newTime); + + VectorClock* getClock() const; + + LogicalTime getClusterTime() const; + + ClockSourceMock* getMockClockSource() const; + + void setMockClockSourceTime(Date_t time) const; + + Date_t getMockClockSourceTime() const; + + DBDirectClient* getDBClient() const; + +private: + VectorClock* _clock; + std::shared_ptr _mockClockSource = std::make_shared(); + std::unique_ptr _dbDirectClient; +}; + +} // namespace mongo diff --git a/src/mongo/dbtests/dbtests.cpp b/src/mongo/dbtests/dbtests.cpp index 0c84bdac851..92e3cccd9c5 100644 --- a/src/mongo/dbtests/dbtests.cpp +++ b/src/mongo/dbtests/dbtests.cpp @@ -46,7 +46,6 @@ #include "mongo/db/commands/test_commands_enabled.h" #include "mongo/db/db_raii.h" #include "mongo/db/index/index_descriptor.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/repl/drop_pending_collection_reaper.h" #include "mongo/db/repl/replication_coordinator.h" #include "mongo/db/repl/replication_coordinator_mock.h" @@ -194,9 +193,6 @@ int dbtestsMain(int argc, char** argv) { const auto service = getGlobalServiceContext(); service->setServiceEntryPoint(std::make_unique(service)); - auto logicalClock = std::make_unique(service); - LogicalClock::set(service, std::move(logicalClock)); - auto fastClock = std::make_unique(); // Timestamps are split into two 32-bit integers, seconds and "increments". Currently (but // maybe not for eternity), a Timestamp with a value of `0` seconds is always considered diff --git a/src/mongo/dbtests/querytests.cpp b/src/mongo/dbtests/querytests.cpp index 04bc9867fa0..4ba7d36c94c 100644 --- a/src/mongo/dbtests/querytests.cpp +++ b/src/mongo/dbtests/querytests.cpp @@ -45,7 +45,6 @@ #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" diff --git a/src/mongo/embedded/embedded.cpp b/src/mongo/embedded/embedded.cpp index 759205529ac..a10e6c975e7 100644 --- a/src/mongo/embedded/embedded.cpp +++ b/src/mongo/embedded/embedded.cpp @@ -49,7 +49,6 @@ #include "mongo/db/global_settings.h" #include "mongo/db/index/index_access_method_factory_impl.h" #include "mongo/db/kill_sessions_local.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_session_cache_impl.h" #include "mongo/db/op_observer_impl.h" #include "mongo/db/op_observer_registry.h" @@ -116,9 +115,6 @@ ServiceContext::ConstructorActionRegisterer replicationManagerInitializer( "CreateReplicationManager", {"SSLManager", "default"}, [](ServiceContext* serviceContext) { repl::StorageInterface::set(serviceContext, std::make_unique()); - auto logicalClock = std::make_unique(serviceContext); - LogicalClock::set(serviceContext, std::move(logicalClock)); - auto replCoord = std::make_unique(serviceContext); repl::ReplicationCoordinator::set(serviceContext, std::move(replCoord)); repl::setOplogCollectionName(serviceContext); diff --git a/src/mongo/embedded/stitch_support/stitch_support.cpp b/src/mongo/embedded/stitch_support/stitch_support.cpp index 090bf4b6958..f6979228d14 100644 --- a/src/mongo/embedded/stitch_support/stitch_support.cpp +++ b/src/mongo/embedded/stitch_support/stitch_support.cpp @@ -36,7 +36,6 @@ #include "mongo/bson/bsonobj.h" #include "mongo/db/exec/projection_executor.h" #include "mongo/db/exec/projection_executor_builder.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/matcher/matcher.h" #include "mongo/db/namespace_string.h" #include "mongo/db/ops/parsed_update_array_filters.h" @@ -125,8 +124,6 @@ ServiceContext* initialize() { uassertStatusOKWithContext(status, "Global initialization failed"); setGlobalServiceContext(ServiceContext::make()); auto serviceContext = getGlobalServiceContext(); - auto logicalClock = std::make_unique(serviceContext); - LogicalClock::set(serviceContext, std::move(logicalClock)); return serviceContext; } diff --git a/src/mongo/rpc/metadata.cpp b/src/mongo/rpc/metadata.cpp index 493d7ddac44..a9747811af1 100644 --- a/src/mongo/rpc/metadata.cpp +++ b/src/mongo/rpc/metadata.cpp @@ -35,7 +35,6 @@ #include "mongo/db/auth/authorization_session.h" #include "mongo/db/dbmessage.h" #include "mongo/db/jsobj.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_time_validator.h" #include "mongo/db/vector_clock.h" #include "mongo/rpc/metadata/client_metadata_ismaster.h" diff --git a/src/mongo/s/catalog_cache.cpp b/src/mongo/s/catalog_cache.cpp index 06e9c878c1b..a470a57bee5 100644 --- a/src/mongo/s/catalog_cache.cpp +++ b/src/mongo/s/catalog_cache.cpp @@ -38,7 +38,6 @@ #include "mongo/s/catalog_cache.h" #include "mongo/bson/bsonobjbuilder.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/query/collation/collator_factory_interface.h" #include "mongo/db/repl/optime_with.h" #include "mongo/logv2/log.h" diff --git a/src/mongo/s/cluster_commands_helpers.cpp b/src/mongo/s/cluster_commands_helpers.cpp index ac9c9900281..14c008bbaa3 100644 --- a/src/mongo/s/cluster_commands_helpers.cpp +++ b/src/mongo/s/cluster_commands_helpers.cpp @@ -39,7 +39,6 @@ #include "mongo/db/commands.h" #include "mongo/db/curop.h" #include "mongo/db/error_labels.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/namespace_string.h" #include "mongo/db/pipeline/expression_context.h" #include "mongo/db/pipeline/process_interface/mongo_process_interface.h" diff --git a/src/mongo/s/commands/cluster_command_test_fixture.cpp b/src/mongo/s/commands/cluster_command_test_fixture.cpp index 31bee683dbf..316fc78782f 100644 --- a/src/mongo/s/commands/cluster_command_test_fixture.cpp +++ b/src/mongo/s/commands/cluster_command_test_fixture.cpp @@ -37,7 +37,6 @@ #include "mongo/db/commands/txn_cmds_gen.h" #include "mongo/db/keys_collection_client_sharded.h" #include "mongo/db/keys_collection_manager.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_session_cache_noop.h" #include "mongo/db/logical_time_validator.h" #include "mongo/db/vector_clock.h" @@ -52,9 +51,7 @@ void ClusterCommandTestFixture::setUp() { CatalogCacheTestFixture::setUp(); CatalogCacheTestFixture::setupNShards(numShards); - // Set up a logical clock with an initial time. - auto logicalClock = std::make_unique(getServiceContext()); - LogicalClock::set(getServiceContext(), std::move(logicalClock)); + // Set the initial clusterTime. VectorClock::get(getServiceContext())->advanceClusterTime_forTest(kInMemoryLogicalTime); auto keysCollectionClient = std::make_unique( diff --git a/src/mongo/s/commands/cluster_write_cmd.cpp b/src/mongo/s/commands/cluster_write_cmd.cpp index fbaced5e4b7..1340e023275 100644 --- a/src/mongo/s/commands/cluster_write_cmd.cpp +++ b/src/mongo/s/commands/cluster_write_cmd.cpp @@ -40,7 +40,6 @@ #include "mongo/db/commands/write_commands/write_commands_common.h" #include "mongo/db/curop.h" #include "mongo/db/lasterror.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/pipeline/lite_parsed_pipeline.h" #include "mongo/db/stats/counters.h" #include "mongo/db/storage/duplicate_key_error_info.h" diff --git a/src/mongo/s/commands/strategy.cpp b/src/mongo/s/commands/strategy.cpp index f83b490d0ef..558524ee17b 100644 --- a/src/mongo/s/commands/strategy.cpp +++ b/src/mongo/s/commands/strategy.cpp @@ -49,7 +49,6 @@ #include "mongo/db/initialize_api_parameters.h" #include "mongo/db/initialize_operation_session_info.h" #include "mongo/db/lasterror.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_session_id_helpers.h" #include "mongo/db/logical_time_validator.h" #include "mongo/db/matcher/extensions_callback_noop.h" @@ -648,13 +647,13 @@ void runCommand(OperationContext* opCtx, (!readConcernArgs.getArgsAtClusterTime() || readConcernArgs.wasAtClusterTimeSelected())) { auto atClusterTime = [&] { - auto latestKnownClusterTime = LogicalClock::get(opCtx)->getClusterTime(); + const auto latestKnownTime = VectorClock::get(opCtx)->getTime(); // Choose a time after the user-supplied afterClusterTime. auto afterClusterTime = readConcernArgs.getArgsAfterClusterTime(); - if (afterClusterTime && *afterClusterTime > latestKnownClusterTime) { + if (afterClusterTime && *afterClusterTime > latestKnownTime.clusterTime()) { return afterClusterTime->asTimestamp(); } - return latestKnownClusterTime.asTimestamp(); + return latestKnownTime.clusterTime().asTimestamp(); }(); readConcernArgs.setArgsAtClusterTimeForSnapshot(atClusterTime); } diff --git a/src/mongo/s/grid.cpp b/src/mongo/s/grid.cpp index ea28033590e..0fb2cf8d2ee 100644 --- a/src/mongo/s/grid.cpp +++ b/src/mongo/s/grid.cpp @@ -124,8 +124,8 @@ void Grid::setAllowLocalHost(bool allow) { repl::ReadConcernArgs Grid::readConcernWithConfigTime( repl::ReadConcernLevel readConcernLevel) const { if (fcvGreaterThanOrEqualTo47()) { - auto now = VectorClock::get(grid.owner(this))->getTime(); - if (auto configTime = now.configTime(); !configTime.asTimestamp().isNull()) { + const auto currentTime = VectorClock::get(grid.owner(this))->getTime(); + if (auto configTime = currentTime.configTime(); !configTime.asTimestamp().isNull()) { // TODO SERVER-44097: investigate why not using a term (e.g. with a LogicalTime) // can lead - upon CSRS stepdowns - to a last applied opTime lower than the // previous primary's committed opTime @@ -140,8 +140,8 @@ repl::ReadConcernArgs Grid::readConcernWithConfigTime( ReadPreferenceSetting Grid::readPreferenceWithConfigTime( const ReadPreferenceSetting& readPreference) const { if (fcvGreaterThanOrEqualTo47()) { - auto now = VectorClock::get(grid.owner(this))->getTime(); - if (auto configTime = now.configTime(); !configTime.asTimestamp().isNull()) { + const auto currentTime = VectorClock::get(grid.owner(this))->getTime(); + if (auto configTime = currentTime.configTime(); !configTime.asTimestamp().isNull()) { ReadPreferenceSetting readPrefToReturn(readPreference); readPrefToReturn.minClusterTime = configTime.asTimestamp(); return readPrefToReturn; diff --git a/src/mongo/s/mongos_main.cpp b/src/mongo/s/mongos_main.cpp index e55cdb0d7d7..e3440eb151e 100644 --- a/src/mongo/s/mongos_main.cpp +++ b/src/mongo/s/mongos_main.cpp @@ -59,7 +59,6 @@ #include "mongo/db/kill_sessions.h" #include "mongo/db/lasterror.h" #include "mongo/db/log_process_details.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_session_cache_impl.h" #include "mongo/db/logical_time_metadata_hook.h" #include "mongo/db/logical_time_validator.h" @@ -724,8 +723,6 @@ ExitCode runMongosServer(ServiceContext* serviceContext) { quickExit(EXIT_BADOPTIONS); } - LogicalClock::set(serviceContext, std::make_unique(serviceContext)); - ReadWriteConcernDefaults::create(serviceContext, readWriteConcernDefaultsCacheLookupMongoS); auto opCtxHolder = tc->makeOperationContext(); diff --git a/src/mongo/s/query/cluster_aggregate.cpp b/src/mongo/s/query/cluster_aggregate.cpp index 279c425ec68..4b2da5f2b34 100644 --- a/src/mongo/s/query/cluster_aggregate.cpp +++ b/src/mongo/s/query/cluster_aggregate.cpp @@ -39,7 +39,6 @@ #include "mongo/db/client.h" #include "mongo/db/commands.h" #include "mongo/db/curop.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/operation_context.h" #include "mongo/db/pipeline/document_source_change_stream.h" #include "mongo/db/pipeline/document_source_out.h" diff --git a/src/mongo/s/query/cluster_find.cpp b/src/mongo/s/query/cluster_find.cpp index 57925b873ed..395f8080acd 100644 --- a/src/mongo/s/query/cluster_find.cpp +++ b/src/mongo/s/query/cluster_find.cpp @@ -45,7 +45,6 @@ #include "mongo/db/commands.h" #include "mongo/db/curop.h" #include "mongo/db/curop_failpoint_helpers.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/query/canonical_query.h" #include "mongo/db/query/find_common.h" #include "mongo/db/query/getmore_request.h" diff --git a/src/mongo/s/query/sharded_agg_test_fixture.h b/src/mongo/s/query/sharded_agg_test_fixture.h index 0bfedd9f5db..c03354f9e5d 100644 --- a/src/mongo/s/query/sharded_agg_test_fixture.h +++ b/src/mongo/s/query/sharded_agg_test_fixture.h @@ -29,7 +29,6 @@ #pragma once -#include "mongo/db/logical_clock.h" #include "mongo/db/pipeline/document_source.h" #include "mongo/db/pipeline/expression_context_for_test.h" #include "mongo/db/pipeline/process_interface/stub_mongo_process_interface.h" @@ -58,8 +57,6 @@ public: void setUp() { CatalogCacheTestFixture::setUp(); - auto serviceCtx = operationContext()->getServiceContext(); - LogicalClock::set(serviceCtx, std::make_unique(serviceCtx)); _expCtx = make_intrusive(operationContext(), kTestAggregateNss); _expCtx->mongoProcessInterface = std::make_shared(executor()); _expCtx->inMongos = true; diff --git a/src/mongo/s/sessions_collection_sharded_test.cpp b/src/mongo/s/sessions_collection_sharded_test.cpp index 89081e468c6..aab98efcbde 100644 --- a/src/mongo/s/sessions_collection_sharded_test.cpp +++ b/src/mongo/s/sessions_collection_sharded_test.cpp @@ -33,7 +33,6 @@ #include "mongo/client/remote_command_targeter_factory_mock.h" #include "mongo/client/remote_command_targeter_mock.h" #include "mongo/db/commands.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_session_id.h" #include "mongo/s/catalog/type_shard.h" #include "mongo/s/catalog_cache_test_fixture.h" @@ -203,4 +202,4 @@ TEST_F(SessionsCollectionShardedTest, RemoveOneSessionWriteErrTest) { } } // namespace -} // namespace mongo \ No newline at end of file +} // namespace mongo diff --git a/src/mongo/s/sharding_initialization.cpp b/src/mongo/s/sharding_initialization.cpp index 2b73154e767..af0cb15f5ea 100644 --- a/src/mongo/s/sharding_initialization.cpp +++ b/src/mongo/s/sharding_initialization.cpp @@ -40,7 +40,6 @@ #include "mongo/db/audit.h" #include "mongo/db/keys_collection_client_sharded.h" #include "mongo/db/keys_collection_manager.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_time_validator.h" #include "mongo/db/server_options.h" #include "mongo/db/service_context.h" diff --git a/src/mongo/s/transaction_router.cpp b/src/mongo/s/transaction_router.cpp index c269d734365..43a6f6ad32c 100644 --- a/src/mongo/s/transaction_router.cpp +++ b/src/mongo/s/transaction_router.cpp @@ -39,10 +39,10 @@ #include "mongo/db/commands/txn_cmds_gen.h" #include "mongo/db/commands/txn_two_phase_commit_cmds_gen.h" #include "mongo/db/jsobj.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_session_id.h" #include "mongo/db/repl/read_concern_args.h" #include "mongo/db/transaction_validation.h" +#include "mongo/db/vector_clock.h" #include "mongo/executor/task_executor_pool.h" #include "mongo/logv2/log.h" #include "mongo/rpc/get_status_from_command_result.h" @@ -860,9 +860,10 @@ void TransactionRouter::Router::setDefaultAtClusterTime(OperationContext* opCtx) return; } - auto defaultTime = LogicalClock::get(opCtx)->getClusterTime(); - _setAtClusterTime( - opCtx, repl::ReadConcernArgs::get(opCtx).getArgsAfterClusterTime(), defaultTime); + const auto defaultTime = VectorClock::get(opCtx)->getTime(); + _setAtClusterTime(opCtx, + repl::ReadConcernArgs::get(opCtx).getArgsAfterClusterTime(), + defaultTime.clusterTime()); } void TransactionRouter::Router::_setAtClusterTime( diff --git a/src/mongo/s/transaction_router_test.cpp b/src/mongo/s/transaction_router_test.cpp index a507d3e4f3f..bd6e503c0e1 100644 --- a/src/mongo/s/transaction_router_test.cpp +++ b/src/mongo/s/transaction_router_test.cpp @@ -36,7 +36,6 @@ #include "mongo/client/remote_command_targeter_mock.h" #include "mongo/db/commands.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/namespace_string.h" #include "mongo/db/repl/read_concern_args.h" #include "mongo/db/vector_clock.h" @@ -123,9 +122,7 @@ protected: repl::ReadConcernArgs::get(operationContext()) = repl::ReadConcernArgs(repl::ReadConcernLevel::kSnapshotReadConcern); - // Set up a logical clock with an initial time. - auto logicalClock = std::make_unique(getServiceContext()); - LogicalClock::set(getServiceContext(), std::move(logicalClock)); + // Set the initial clusterTime. VectorClock::get(getServiceContext())->advanceClusterTime_forTest(kInMemoryLogicalTime); // Set up a tick source for transaction metrics. diff --git a/src/mongo/s/write_ops/batch_write_exec_test.cpp b/src/mongo/s/write_ops/batch_write_exec_test.cpp index bdadf82b80d..25e5385ec90 100644 --- a/src/mongo/s/write_ops/batch_write_exec_test.cpp +++ b/src/mongo/s/write_ops/batch_write_exec_test.cpp @@ -33,7 +33,6 @@ #include "mongo/client/remote_command_targeter_factory_mock.h" #include "mongo/client/remote_command_targeter_mock.h" #include "mongo/db/commands.h" -#include "mongo/db/logical_clock.h" #include "mongo/db/logical_session_id.h" #include "mongo/db/vector_clock.h" #include "mongo/s/catalog/type_shard.h" @@ -1609,8 +1608,6 @@ public: repl::ReadConcernArgs::get(operationContext()) = repl::ReadConcernArgs(repl::ReadConcernLevel::kSnapshotReadConcern); - auto logicalClock = std::make_unique(getServiceContext()); - LogicalClock::set(getServiceContext(), std::move(logicalClock)); VectorClock::get(getServiceContext())->advanceClusterTime_forTest(kInMemoryLogicalTime); _scopedSession.emplace(operationContext()); -- cgit v1.2.1