summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTommaso Tocci <tommaso.tocci@mongodb.com>2020-05-06 23:24:10 +0200
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-05-12 11:41:20 +0000
commitf6609ee18cd063170391578a9afaee047eee28a7 (patch)
tree72c7670f25aa17681c2232b0144a0a9b0dfc885c
parent0f9e013c5f3cf3a8fa91b7b5e757d00bb2deae5b (diff)
downloadmongo-f6609ee18cd063170391578a9afaee047eee28a7.tar.gz
SERVER-47974 Introduce ScopedShardVersionCriticalSection class
-rw-r--r--src/mongo/db/s/SConscript1
-rw-r--r--src/mongo/db/s/scoped_shard_version_critical_section.cpp76
-rw-r--r--src/mongo/db/s/scoped_shard_version_critical_section.h57
-rw-r--r--src/mongo/db/s/shardsvr_shard_collection.cpp7
4 files changed, 136 insertions, 5 deletions
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
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * 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
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * 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<InitialSplitPolicy> splitPolicy;
InitialSplitPolicy::ShardCollectionConfig initialChunks;
boost::optional<ShardCollectionTargetState> 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();