From f6609ee18cd063170391578a9afaee047eee28a7 Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Wed, 6 May 2020 23:24:10 +0200 Subject: SERVER-47974 Introduce ScopedShardVersionCriticalSection class --- src/mongo/db/s/SConscript | 1 + .../db/s/scoped_shard_version_critical_section.cpp | 76 ++++++++++++++++++++++ .../db/s/scoped_shard_version_critical_section.h | 57 ++++++++++++++++ src/mongo/db/s/shardsvr_shard_collection.cpp | 7 +- 4 files changed, 136 insertions(+), 5 deletions(-) create mode 100644 src/mongo/db/s/scoped_shard_version_critical_section.cpp create mode 100644 src/mongo/db/s/scoped_shard_version_critical_section.h diff --git a/src/mongo/db/s/SConscript b/src/mongo/db/s/SConscript index 9a38b35721b..66fd73a851d 100644 --- a/src/mongo/db/s/SConscript +++ b/src/mongo/db/s/SConscript @@ -67,6 +67,7 @@ env.Library( 'range_deletion_util.cpp', 'read_only_catalog_cache_loader.cpp', 'scoped_operation_completion_sharding_actions.cpp', + 'scoped_shard_version_critical_section.cpp', 'session_catalog_migration_destination.cpp', 'session_catalog_migration_source.cpp', 'shard_filtering_metadata_refresh.cpp', diff --git a/src/mongo/db/s/scoped_shard_version_critical_section.cpp b/src/mongo/db/s/scoped_shard_version_critical_section.cpp new file mode 100644 index 00000000000..6be946fc1b0 --- /dev/null +++ b/src/mongo/db/s/scoped_shard_version_critical_section.cpp @@ -0,0 +1,76 @@ +/** + * 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/s/scoped_shard_version_critical_section.h" + +#include "mongo/db/catalog_raii.h" +#include "mongo/db/s/shard_filtering_metadata_refresh.h" + +namespace mongo { + +ScopedShardVersionCriticalSection::ScopedShardVersionCriticalSection(OperationContext* opCtx, + NamespaceString nss) + : _nss(std::move(nss)), _opCtx(opCtx) { + + { + // Enters the commit phase of the critical section and blocks reads + AutoGetCollection autoColl(_opCtx, + _nss, + MODE_X, + AutoGetCollection::ViewMode::kViewsForbidden, + _opCtx->getServiceContext()->getPreciseClockSource()->now() + + Milliseconds(migrationLockAcquisitionMaxWaitMS.load())); + auto* const csr = CollectionShardingRuntime::get(_opCtx, _nss); + csr->enterCriticalSectionCatchUpPhase(_opCtx); + } + + forceShardFilteringMetadataRefresh(_opCtx, _nss, true); +} + +ScopedShardVersionCriticalSection::~ScopedShardVersionCriticalSection() { + UninterruptibleLockGuard noInterrupt(_opCtx->lockState()); + AutoGetCollection autoColl(_opCtx, _nss, MODE_IX); + auto* const csr = CollectionShardingRuntime::get(_opCtx, _nss); + csr->exitCriticalSection(_opCtx); +} + +void ScopedShardVersionCriticalSection::enterCommitPhase() { + AutoGetCollection autoColl(_opCtx, + _nss, + MODE_X, + AutoGetCollection::ViewMode::kViewsForbidden, + _opCtx->getServiceContext()->getPreciseClockSource()->now() + + Milliseconds(migrationLockAcquisitionMaxWaitMS.load())); + auto* const csr = CollectionShardingRuntime::get(_opCtx, _nss); + csr->enterCriticalSectionCommitPhase(_opCtx); +} + +} // namespace mongo diff --git a/src/mongo/db/s/scoped_shard_version_critical_section.h b/src/mongo/db/s/scoped_shard_version_critical_section.h new file mode 100644 index 00000000000..d5ec579313e --- /dev/null +++ b/src/mongo/db/s/scoped_shard_version_critical_section.h @@ -0,0 +1,57 @@ +/** + * 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/namespace_string.h" +#include "mongo/db/s/collection_sharding_runtime.h" + +namespace mongo { + +/** + * RAII-style class that enters the migration critical section and refresh the filtering + * metadata for the specified collection. The critical section is released when this object + * goes out of scope. + */ +class ScopedShardVersionCriticalSection { + ScopedShardVersionCriticalSection(const ScopedShardVersionCriticalSection&) = delete; + ScopedShardVersionCriticalSection& operator=(const ScopedShardVersionCriticalSection&) = delete; + +public: + ScopedShardVersionCriticalSection(OperationContext* opCtx, NamespaceString nss); + ~ScopedShardVersionCriticalSection(); + + void enterCommitPhase(); + +private: + const NamespaceString _nss; + OperationContext* _opCtx; +}; + +} // namespace mongo diff --git a/src/mongo/db/s/shardsvr_shard_collection.cpp b/src/mongo/db/s/shardsvr_shard_collection.cpp index 15b0464553d..081033eccf1 100644 --- a/src/mongo/db/s/shardsvr_shard_collection.cpp +++ b/src/mongo/db/s/shardsvr_shard_collection.cpp @@ -48,6 +48,7 @@ #include "mongo/db/s/collection_sharding_runtime.h" #include "mongo/db/s/config/initial_split_policy.h" #include "mongo/db/s/config/sharding_catalog_manager.h" +#include "mongo/db/s/scoped_shard_version_critical_section.h" #include "mongo/db/s/shard_filtering_metadata_refresh.h" #include "mongo/db/s/shard_key_util.h" #include "mongo/db/s/sharding_logging.h" @@ -461,10 +462,6 @@ UUID shardCollection(OperationContext* opCtx, return *collectionOptional->getUUID(); } - // Make sure that this shard initializes the collection metadata so we can perform local - // operations without getting stale config exception. - forceShardFilteringMetadataRefresh(opCtx, nss, true); - std::unique_ptr splitPolicy; InitialSplitPolicy::ShardCollectionConfig initialChunks; boost::optional targetState; @@ -490,7 +487,7 @@ UUID shardCollection(OperationContext* opCtx, { // From this point onward the collection can only be read, not written to, so it is safe to // construct the prerequisites and generate the target state. - CollectionCriticalSection critSec(opCtx, nss); + ScopedShardVersionCriticalSection critSec(opCtx, nss); pauseShardCollectionReadOnlyCriticalSection.pauseWhileSet(); -- cgit v1.2.1