diff options
Diffstat (limited to 'src/mongo/db/s/implicit_create_collection.cpp')
-rw-r--r-- | src/mongo/db/s/implicit_create_collection.cpp | 181 |
1 files changed, 0 insertions, 181 deletions
diff --git a/src/mongo/db/s/implicit_create_collection.cpp b/src/mongo/db/s/implicit_create_collection.cpp deleted file mode 100644 index b146eeb5076..00000000000 --- a/src/mongo/db/s/implicit_create_collection.cpp +++ /dev/null @@ -1,181 +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 - * <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. - */ - -#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kSharding - -#include "mongo/platform/basic.h" - -#include "mongo/db/s/implicit_create_collection.h" - -#include <map> -#include <memory> -#include <string> - -#include "mongo/db/catalog/database_holder.h" -#include "mongo/db/catalog_raii.h" -#include "mongo/db/commands.h" -#include "mongo/db/namespace_string.h" -#include "mongo/db/operation_context.h" -#include "mongo/db/service_context.h" -#include "mongo/s/grid.h" -#include "mongo/s/request_types/create_collection_gen.h" - -#include "mongo/platform/mutex.h" -#include "mongo/stdx/condition_variable.h" -#include "mongo/util/scopeguard.h" - -namespace mongo { - -namespace { - -/** - * Responsible for explicitly creating collections in the sharding catalog. Also takes care of - * making sure that concurrent attempts to create a collection for the same ns will be - * synchronized and avoid duplicate work as much as possible. - */ - -class CreateCollectionSerializer { -public: - explicit CreateCollectionSerializer(NamespaceString ns) : _ns(std::move(ns)) {} - - /** - * Initialize this collection so it will be officially tracked in a sharded environment - * by sending the command to the config server to create an entry for this collection in - * the sharding catalog. - */ - Status onCannotImplicitlyCreateCollection(OperationContext* opCtx) noexcept { - invariant(!opCtx->lockState()->isLocked()); - - try { - stdx::unique_lock<Latch> lg(_mutex); - - opCtx->waitForConditionOrInterrupt(_cvIsInProgress, lg, [&] { return !_isInProgress; }); - - _isInProgress = true; - } catch (const DBException& e) { - return e.toStatus(); - } - - ON_BLOCK_EXIT([&] { - stdx::lock_guard<Latch> lg(_mutex); - _isInProgress = false; - _cvIsInProgress.notify_one(); - }); - - try { - // Take the DBLock and CollectionLock directly rather than using AutoGetCollection - // (which calls AutoGetDb) to avoid doing database and shard version checks. - Lock::DBLock dbLock(opCtx, _ns.db(), MODE_IS); - auto databaseHolder = DatabaseHolder::get(opCtx); - auto db = databaseHolder->getDb(opCtx, _ns.db()); - if (db) { - Lock::CollectionLock collLock(opCtx, _ns, MODE_IS); - if (CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, _ns)) { - // Collection already created, no more work needs to be done. - return Status::OK(); - } - } - } catch (const DBException& ex) { - return ex.toStatus(); - } - - ConfigsvrCreateCollection configCreateCmd(_ns); - configCreateCmd.setDbName(NamespaceString::kAdminDb); - - auto statusWith = - Grid::get(opCtx)->shardRegistry()->getConfigShard()->runCommandWithFixedRetryAttempts( - opCtx, - ReadPreferenceSetting{ReadPreference::PrimaryOnly}, - NamespaceString::kAdminDb.toString(), - CommandHelpers::appendMajorityWriteConcern(configCreateCmd.toBSON({})), - Shard::RetryPolicy::kIdempotent); - - if (!statusWith.isOK()) { - return statusWith.getStatus(); - } - - return Shard::CommandResponse::getEffectiveStatus(statusWith.getValue()); - } - -private: - const NamespaceString _ns; - - Mutex _mutex = MONGO_MAKE_LATCH("CreateCollectionSerializer::_mutex"); - stdx::condition_variable _cvIsInProgress; - bool _isInProgress = false; -}; - -class CreateCollectionSerializerMap { -public: - std::shared_ptr<CreateCollectionSerializer> getForNs(const NamespaceString& ns) { - stdx::lock_guard<Latch> lg(_mutex); - auto iter = _inProgressMap.find(ns.ns()); - if (iter == _inProgressMap.end()) { - std::tie(iter, std::ignore) = - _inProgressMap.emplace(ns.ns(), std::make_shared<CreateCollectionSerializer>(ns)); - } - - return iter->second; - } - - void cleanupNs(const NamespaceString& ns) { - stdx::lock_guard<Latch> lg(_mutex); - _inProgressMap.erase(ns.ns()); - } - -private: - Mutex _mutex = MONGO_MAKE_LATCH("CreateCollectionSerializerMap::_mutex"); - std::map<std::string, std::shared_ptr<CreateCollectionSerializer>> _inProgressMap; -}; - -const auto createCollectionSerializerMap = - ServiceContext::declareDecoration<CreateCollectionSerializerMap>(); - -} // unnamed namespace - -Status onCannotImplicitlyCreateCollection(OperationContext* opCtx, - const NamespaceString& ns) noexcept { - auto& handlerMap = createCollectionSerializerMap(opCtx->getServiceContext()); - auto status = handlerMap.getForNs(ns)->onCannotImplicitlyCreateCollection(opCtx); - - if (status.isOK()) { - handlerMap.cleanupNs(ns); - } else { - // We only cleanup on success because that is our last chance for us to do so. This avoids - // the scenario with multiple handlers for the same ns to exist at the same time if we - // cleanup regardless of success or failure. On the other hand, cleaning it up only on - // success can cause the handler to never get cleaned up when the collection was - // successfully created, but this shard got an error response from the config - // server. - } - - return status; -} - -} // namespace mongo |