summaryrefslogtreecommitdiff
path: root/src/mongo/idl
diff options
context:
space:
mode:
authorLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
committerLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
commit4cb8841196d0625dfa3825aa326f071cd27c7b8b (patch)
tree1682a647d4463397c119183369ae6f750d5fdcff /src/mongo/idl
parentaa03c6362cbaa767638e6eed9b031d86dd2643d1 (diff)
parent8f0827553e09872941945a093b647a4211a9db7f (diff)
Update upstream source from tag 'upstream/6.0.0'master
Update to upstream version '6.0.0' with Debian dir 5604a80ec1c96ca76f25f40d78e6ef855abec322
Diffstat (limited to 'src/mongo/idl')
-rw-r--r--src/mongo/idl/SConscript20
-rw-r--r--src/mongo/idl/basic_types.h5
-rw-r--r--src/mongo/idl/basic_types.idl7
-rw-r--r--src/mongo/idl/cluster_parameter_synchronization_helpers.cpp147
-rw-r--r--src/mongo/idl/cluster_parameter_synchronization_helpers.h105
-rw-r--r--src/mongo/idl/cluster_server_parameter_initializer.cpp95
-rw-r--r--src/mongo/idl/cluster_server_parameter_initializer.h46
-rw-r--r--src/mongo/idl/cluster_server_parameter_initializer_test.cpp3
-rw-r--r--src/mongo/idl/cluster_server_parameter_op_observer.cpp63
-rw-r--r--src/mongo/idl/cluster_server_parameter_op_observer.h19
-rw-r--r--src/mongo/idl/cluster_server_parameter_op_observer_test.cpp173
-rw-r--r--src/mongo/idl/server_parameter_test_util.h43
12 files changed, 292 insertions, 434 deletions
diff --git a/src/mongo/idl/SConscript b/src/mongo/idl/SConscript
index a95eb570aa5..2fcbf03c37a 100644
--- a/src/mongo/idl/SConscript
+++ b/src/mongo/idl/SConscript
@@ -74,23 +74,7 @@ env.Library(
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/dbdirectclient',
'$BUILD_DIR/mongo/db/repl/replica_set_aware_service',
- 'cluster_parameter_synchronization_helpers',
- ],
-)
-
-env.Library(
- target='cluster_parameter_synchronization_helpers',
- source=[
- 'cluster_parameter_synchronization_helpers.cpp',
- ],
- LIBDEPS=[
- '$BUILD_DIR/mongo/base',
- ],
- LIBDEPS_PRIVATE=[
- '$BUILD_DIR/mongo/db/audit',
- '$BUILD_DIR/mongo/db/db_raii',
- '$BUILD_DIR/mongo/db/logical_time',
- ],
+ ]
)
env.Library(
@@ -104,7 +88,6 @@ env.Library(
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/dbdirectclient',
'$BUILD_DIR/mongo/db/op_observer',
- 'cluster_parameter_synchronization_helpers',
'cluster_server_parameter_initializer',
],
)
@@ -153,7 +136,6 @@ env.CppUnitTest(
'$BUILD_DIR/mongo/db/repl/storage_interface_impl',
'$BUILD_DIR/mongo/db/service_context_d_test_fixture',
'$BUILD_DIR/mongo/util/signal_handlers',
- 'cluster_parameter_synchronization_helpers',
'cluster_server_parameter_initializer',
'cluster_server_parameter_test_parameter',
],
diff --git a/src/mongo/idl/basic_types.h b/src/mongo/idl/basic_types.h
index 4f93115bf0c..4b77f57461d 100644
--- a/src/mongo/idl/basic_types.h
+++ b/src/mongo/idl/basic_types.h
@@ -127,11 +127,6 @@ private:
boost::optional<bool> _value;
};
-template <typename H>
-H AbslHashValue(H h, const OptionalBool& optBool) {
- return H::combine(std::move(h), optBool.has_value(), bool(optBool));
-}
-
/**
* Class to represent a BSON element with any type from IDL. The caller must ensure that the backing
* BSON stays alive while this type is in use.
diff --git a/src/mongo/idl/basic_types.idl b/src/mongo/idl/basic_types.idl
index e41c18b7714..634b05d9539 100644
--- a/src/mongo/idl/basic_types.idl
+++ b/src/mongo/idl/basic_types.idl
@@ -163,13 +163,6 @@ types:
cpp_type: "std::vector<std::uint8_t>"
deserializer: "mongo::BSONElement::_binDataVector"
- bindata_sensitive:
- bson_serialization_type: bindata
- bindata_subtype: sensitive
- description: "A BSON bindata of sensitive sub type"
- cpp_type: "std::vector<std::uint8_t>"
- deserializer: "mongo::BSONElement::_binDataVector"
-
uuid:
bson_serialization_type: bindata
bindata_subtype: uuid
diff --git a/src/mongo/idl/cluster_parameter_synchronization_helpers.cpp b/src/mongo/idl/cluster_parameter_synchronization_helpers.cpp
deleted file mode 100644
index 1566c42fa8e..00000000000
--- a/src/mongo/idl/cluster_parameter_synchronization_helpers.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/**
- * Copyright (C) 2023-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_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kControl
-
-#include "mongo/idl/cluster_parameter_synchronization_helpers.h"
-
-#include "mongo/base/string_data.h"
-#include "mongo/db/audit.h"
-#include "mongo/db/catalog_raii.h"
-#include "mongo/db/multitenancy_gen.h"
-#include "mongo/logv2/log.h"
-
-namespace mongo::cluster_parameters {
-
-constexpr auto kIdField = "_id"_sd;
-constexpr auto kCPTField = "clusterParameterTime"_sd;
-constexpr auto kOplog = "oplog"_sd;
-
-void updateParameter(BSONObj doc, StringData mode) {
- auto nameElem = doc[kIdField];
- if (nameElem.type() != String) {
- LOGV2_DEBUG(6226301,
- 1,
- "Update with invalid cluster server parameter name",
- "mode"_attr = mode,
- "_id"_attr = nameElem);
- return;
- }
-
- auto name = nameElem.valueStringData();
- auto* sp = ServerParameterSet::getClusterParameterSet()->getIfExists(name);
- if (!sp) {
- LOGV2_DEBUG(6226300,
- 3,
- "Update to unknown cluster server parameter",
- "mode"_attr = mode,
- "name"_attr = name);
- return;
- }
-
- auto cptElem = doc[kCPTField];
- if ((cptElem.type() != mongo::Date) && (cptElem.type() != bsonTimestamp)) {
- LOGV2_DEBUG(6226302,
- 1,
- "Update to cluster server parameter has invalid clusterParameterTime",
- "mode"_attr = mode,
- "name"_attr = name,
- "clusterParameterTime"_attr = cptElem);
- return;
- }
-
- uassertStatusOK(sp->set(doc));
-}
-
-void clearParameter(ServerParameter* sp) {
- if (sp->getClusterParameterTime() == LogicalTime::kUninitialized) {
- // Nothing to clear.
- return;
- }
-
- uassertStatusOK(sp->reset());
-}
-
-void clearParameter(StringData id) {
- auto* sp = ServerParameterSet::getClusterParameterSet()->getIfExists(id);
- if (!sp) {
- LOGV2_DEBUG(6226303,
- 5,
- "oplog event deletion of unknown cluster server parameter",
- "name"_attr = id);
- return;
- }
-
- clearParameter(sp);
-}
-
-void clearAllParameters() {
- const auto& params = ServerParameterSet::getClusterParameterSet()->getMap();
- for (const auto& it : params) {
- clearParameter(it.second);
- }
-}
-
-void initializeAllParametersFromDisk(OperationContext* opCtx) {
- doLoadAllParametersFromDisk(
- opCtx, "initializing"_sd, [](OperationContext* opCtx, BSONObj doc, StringData mode) {
- updateParameter(doc, mode);
- });
-}
-
-void resynchronizeAllParametersFromDisk(OperationContext* opCtx) {
- const auto& allParams = ServerParameterSet::getClusterParameterSet()->getMap();
- std::set<std::string> unsetSettings;
- for (const auto& it : allParams) {
- unsetSettings.insert(it.second->name());
- }
-
- doLoadAllParametersFromDisk(
- opCtx,
- "resynchronizing"_sd,
- [&unsetSettings](OperationContext* opCtx, BSONObj doc, StringData mode) {
- unsetSettings.erase(doc[kIdField].str());
- updateParameter(doc, mode);
- });
-
- // For all known settings which were not present in this resync,
- // explicitly clear any value which may be present in-memory.
- for (const auto& setting : unsetSettings) {
- clearParameter(setting);
- }
-}
-
-void maybeUpdateClusterParametersPostImportCollectionCommit(OperationContext* opCtx,
- const NamespaceString& nss) {
- if (nss == NamespaceString::kClusterParametersNamespace) {
- // Something was imported, do a full collection scan to sync up.
- cluster_parameters::initializeAllParametersFromDisk(opCtx);
- }
-}
-
-} // namespace mongo::cluster_parameters
diff --git a/src/mongo/idl/cluster_parameter_synchronization_helpers.h b/src/mongo/idl/cluster_parameter_synchronization_helpers.h
deleted file mode 100644
index d69271a7c03..00000000000
--- a/src/mongo/idl/cluster_parameter_synchronization_helpers.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * Copyright (C) 2023-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/db_raii.h"
-
-namespace mongo {
-
-namespace cluster_parameters {
-
-void updateParameter(BSONObj doc, StringData mode);
-
-void clearParameter(ServerParameter* sp);
-
-void clearParameter(StringData id);
-
-void clearAllParameters();
-
-/**
- * Used to initialize in-memory cluster parameter state based on the on-disk contents after startup
- * recovery or initial sync is complete.
- */
-void initializeAllParametersFromDisk(OperationContext* opCtx);
-
-/**
- * Used on rollback. Updates settings which are present and clears settings which are not.
- */
-void resynchronizeAllParametersFromDisk(OperationContext* opCtx);
-
-template <typename OnEntry>
-void doLoadAllParametersFromDisk(OperationContext* opCtx, StringData mode, OnEntry onEntry) try {
-
- // If the RecoveryUnit already had an open snapshot, keep the snapshot open. Otherwise
- // abandon the snapshot when exiting the function.
- ScopeGuard scopeGuard([&] { opCtx->recoveryUnit()->abandonSnapshot(); });
- if (opCtx->recoveryUnit()->isActive()) {
- scopeGuard.dismiss();
- }
-
- AutoGetCollectionForRead coll(opCtx, NamespaceString::kClusterParametersNamespace);
- if (!coll) {
- return;
- }
-
- std::vector<Status> failures;
-
- auto cursor = coll->getCursor(opCtx);
- for (auto doc = cursor->next(); doc; doc = cursor->next()) {
- try {
- onEntry(opCtx, doc.get().data.toBson(), mode);
- } catch (const DBException& ex) {
- failures.push_back(ex.toStatus());
- }
- }
-
- if (!failures.empty()) {
- StringBuilder msg;
- for (const auto& failure : failures) {
- msg << failure.toString() << ", ";
- }
- msg.reset(msg.len() - 2);
- uasserted(ErrorCodes::OperationFailed, msg.str());
- }
-} catch (const DBException& ex) {
- uassertStatusOK(ex.toStatus().withContext(
- str::stream() << "Failed " << mode << " cluster server parameters from disk"));
-}
-
-/**
- * Used after an importCollection commits. Will update the in-memory cluster parameter state if the
- * given namespace is a cluster parameters namespace.
- */
-void maybeUpdateClusterParametersPostImportCollectionCommit(OperationContext* opCtx,
- const NamespaceString& nss);
-
-} // namespace cluster_parameters
-
-} // namespace mongo
diff --git a/src/mongo/idl/cluster_server_parameter_initializer.cpp b/src/mongo/idl/cluster_server_parameter_initializer.cpp
index e28e0542ecb..3205f7a4fa7 100644
--- a/src/mongo/idl/cluster_server_parameter_initializer.cpp
+++ b/src/mongo/idl/cluster_server_parameter_initializer.cpp
@@ -34,7 +34,6 @@
#include "mongo/base/string_data.h"
#include "mongo/db/repl/replica_set_aware_service.h"
#include "mongo/db/service_context.h"
-#include "mongo/idl/cluster_parameter_synchronization_helpers.h"
#include "mongo/logv2/log.h"
namespace mongo {
@@ -59,10 +58,102 @@ ClusterServerParameterInitializer* ClusterServerParameterInitializer::get(
return &getInstance(serviceContext);
}
+void ClusterServerParameterInitializer::updateParameter(BSONObj doc, StringData mode) {
+ auto nameElem = doc[kIdField];
+ if (nameElem.type() != String) {
+ LOGV2_DEBUG(6226301,
+ 1,
+ "Update with invalid cluster server parameter name",
+ "mode"_attr = mode,
+ "_id"_attr = nameElem);
+ return;
+ }
+
+ auto name = nameElem.valueStringData();
+ auto* sp = ServerParameterSet::getClusterParameterSet()->getIfExists(name);
+ if (!sp) {
+ LOGV2_DEBUG(6226300,
+ 3,
+ "Update to unknown cluster server parameter",
+ "mode"_attr = mode,
+ "name"_attr = name);
+ return;
+ }
+
+ auto cptElem = doc[kCPTField];
+ if ((cptElem.type() != mongo::Date) && (cptElem.type() != bsonTimestamp)) {
+ LOGV2_DEBUG(6226302,
+ 1,
+ "Update to cluster server parameter has invalid clusterParameterTime",
+ "mode"_attr = mode,
+ "name"_attr = name,
+ "clusterParameterTime"_attr = cptElem);
+ return;
+ }
+
+ uassertStatusOK(sp->set(doc));
+}
+
+void ClusterServerParameterInitializer::clearParameter(ServerParameter* sp) {
+ if (sp->getClusterParameterTime() == LogicalTime::kUninitialized) {
+ // Nothing to clear.
+ return;
+ }
+
+ uassertStatusOK(sp->reset());
+}
+
+void ClusterServerParameterInitializer::clearParameter(StringData id) {
+ auto* sp = ServerParameterSet::getClusterParameterSet()->getIfExists(id);
+ if (!sp) {
+ LOGV2_DEBUG(6226303,
+ 5,
+ "oplog event deletion of unknown cluster server parameter",
+ "name"_attr = id);
+ return;
+ }
+
+ clearParameter(sp);
+}
+
+void ClusterServerParameterInitializer::clearAllParameters() {
+ const auto& params = ServerParameterSet::getClusterParameterSet()->getMap();
+ for (const auto& it : params) {
+ clearParameter(it.second);
+ }
+}
+
+void ClusterServerParameterInitializer::initializeAllParametersFromDisk(OperationContext* opCtx) {
+ doLoadAllParametersFromDisk(opCtx, "initializing"_sd, [this](BSONObj doc, StringData mode) {
+ updateParameter(doc, mode);
+ });
+}
+
+void ClusterServerParameterInitializer::resynchronizeAllParametersFromDisk(
+ OperationContext* opCtx) {
+ const auto& allParams = ServerParameterSet::getClusterParameterSet()->getMap();
+ std::set<std::string> unsetSettings;
+ for (const auto& it : allParams) {
+ unsetSettings.insert(it.second->name());
+ }
+
+ doLoadAllParametersFromDisk(
+ opCtx, "resynchronizing"_sd, [this, &unsetSettings](BSONObj doc, StringData mode) {
+ unsetSettings.erase(doc[kIdField].str());
+ updateParameter(doc, mode);
+ });
+
+ // For all known settings which were not present in this resync,
+ // explicitly clear any value which may be present in-memory.
+ for (const auto& setting : unsetSettings) {
+ clearParameter(setting);
+ }
+}
+
void ClusterServerParameterInitializer::onInitialDataAvailable(OperationContext* opCtx,
bool isMajorityDataAvailable) {
LOGV2_INFO(6608200, "Initializing cluster server parameters from disk");
- cluster_parameters::initializeAllParametersFromDisk(opCtx);
+ initializeAllParametersFromDisk(opCtx);
}
} // namespace mongo
diff --git a/src/mongo/idl/cluster_server_parameter_initializer.h b/src/mongo/idl/cluster_server_parameter_initializer.h
index 49d501a7e6d..0eb02bb058c 100644
--- a/src/mongo/idl/cluster_server_parameter_initializer.h
+++ b/src/mongo/idl/cluster_server_parameter_initializer.h
@@ -52,6 +52,23 @@ public:
static ClusterServerParameterInitializer* get(OperationContext* opCtx);
static ClusterServerParameterInitializer* get(ServiceContext* serviceContext);
+ void updateParameter(BSONObj doc, StringData mode);
+ void clearParameter(ServerParameter* sp);
+ void clearParameter(StringData id);
+ void clearAllParameters();
+
+ /**
+ * Used to initialize in-memory cluster parameter state based on the on-disk contents after
+ * startup recovery or initial sync is complete.
+ */
+ void initializeAllParametersFromDisk(OperationContext* opCtx);
+
+ /**
+ * Used on rollback and rename with drop.
+ * Updates settings which are present and clears settings which are not.
+ */
+ void resynchronizeAllParametersFromDisk(OperationContext* opCtx);
+
// Virtual methods coming from the ReplicaSetAwareService
void onStartup(OperationContext* opCtx) override final {}
@@ -65,6 +82,35 @@ public:
void onStepUpComplete(OperationContext* opCtx, long long term) override final {}
void onStepDown() override final {}
void onBecomeArbiter() override final {}
+
+private:
+ template <typename OnEntry>
+ void doLoadAllParametersFromDisk(OperationContext* opCtx,
+ StringData mode,
+ OnEntry onEntry) try {
+ std::vector<Status> failures;
+
+ DBDirectClient client(opCtx);
+ FindCommandRequest findRequest{NamespaceString::kClusterParametersNamespace};
+ client.find(std::move(findRequest), ReadPreferenceSetting{}, [&](BSONObj doc) {
+ try {
+ onEntry(doc, mode);
+ } catch (const DBException& ex) {
+ failures.push_back(ex.toStatus());
+ }
+ });
+ if (!failures.empty()) {
+ StringBuilder msg;
+ for (const auto& failure : failures) {
+ msg << failure.toString() << ", ";
+ }
+ msg.reset(msg.len() - 2);
+ uasserted(ErrorCodes::OperationFailed, msg.str());
+ }
+ } catch (const DBException& ex) {
+ uassertStatusOK(ex.toStatus().withContext(
+ str::stream() << "Failed " << mode << " cluster server parameters from disk"));
+ }
};
} // namespace mongo
diff --git a/src/mongo/idl/cluster_server_parameter_initializer_test.cpp b/src/mongo/idl/cluster_server_parameter_initializer_test.cpp
index a2211ed0295..e8a62b6a1c1 100644
--- a/src/mongo/idl/cluster_server_parameter_initializer_test.cpp
+++ b/src/mongo/idl/cluster_server_parameter_initializer_test.cpp
@@ -38,7 +38,6 @@
#include "mongo/db/repl/replication_coordinator_mock.h"
#include "mongo/db/repl/storage_interface_mock.h"
#include "mongo/db/service_context_d_test_fixture.h"
-#include "mongo/idl/cluster_parameter_synchronization_helpers.h"
#include "mongo/idl/cluster_server_parameter_gen.h"
#include "mongo/idl/cluster_server_parameter_initializer.h"
#include "mongo/idl/cluster_server_parameter_test_gen.h"
@@ -69,7 +68,7 @@ public:
// Delete all cluster server parameter documents written and refresh in-memory state.
remove();
auto opCtx = cc().makeOperationContext();
- cluster_parameters::resynchronizeAllParametersFromDisk(opCtx.get());
+ _initializer.resynchronizeAllParametersFromDisk(opCtx.get());
}
/**
* Simulates the call to the ClusterServerParameterInitializer at the end of initial sync, when
diff --git a/src/mongo/idl/cluster_server_parameter_op_observer.cpp b/src/mongo/idl/cluster_server_parameter_op_observer.cpp
index ea9553d46fb..b8787dcfa12 100644
--- a/src/mongo/idl/cluster_server_parameter_op_observer.cpp
+++ b/src/mongo/idl/cluster_server_parameter_op_observer.cpp
@@ -34,7 +34,7 @@
#include <memory>
#include "mongo/db/dbdirectclient.h"
-#include "mongo/idl/cluster_parameter_synchronization_helpers.h"
+#include "mongo/idl/cluster_server_parameter_initializer.h"
#include "mongo/logv2/log.h"
namespace mongo {
@@ -67,9 +67,7 @@ void ClusterServerParameterOpObserver::onInserts(OperationContext* opCtx,
}
for (auto it = first; it != last; ++it) {
- opCtx->recoveryUnit()->onCommit([doc = it->doc](boost::optional<Timestamp>) {
- cluster_parameters::updateParameter(doc, kOplog);
- });
+ ClusterServerParameterInitializer::get(opCtx)->updateParameter(it->doc, kOplog);
}
}
@@ -80,9 +78,7 @@ void ClusterServerParameterOpObserver::onUpdate(OperationContext* opCtx,
return;
}
- opCtx->recoveryUnit()->onCommit([updatedDoc](boost::optional<Timestamp>) {
- cluster_parameters::updateParameter(updatedDoc, kOplog);
- });
+ ClusterServerParameterInitializer::get(opCtx)->updateParameter(updatedDoc, kOplog);
}
void ClusterServerParameterOpObserver::aboutToDelete(OperationContext* opCtx,
@@ -119,8 +115,7 @@ void ClusterServerParameterOpObserver::onDelete(OperationContext* opCtx,
const OplogDeleteEntryArgs& args) {
const auto& docName = aboutToDeleteDoc(opCtx);
if (!docName.empty()) {
- opCtx->recoveryUnit()->onCommit(
- [docName](boost::optional<Timestamp>) { cluster_parameters::clearParameter(docName); });
+ ClusterServerParameterInitializer::get(opCtx)->clearParameter(docName);
}
}
@@ -128,8 +123,7 @@ void ClusterServerParameterOpObserver::onDropDatabase(OperationContext* opCtx,
const std::string& dbName) {
if (dbName == NamespaceString::kConfigDb) {
// Entire config DB deleted, reset to default state.
- opCtx->recoveryUnit()->onCommit(
- [](boost::optional<Timestamp>) { cluster_parameters::clearAllParameters(); });
+ ClusterServerParameterInitializer::get(opCtx)->clearAllParameters();
}
}
@@ -141,21 +135,58 @@ repl::OpTime ClusterServerParameterOpObserver::onDropCollection(
CollectionDropType dropType) {
if (isConfigNamespace(collectionName)) {
// Entire collection deleted, reset to default state.
- opCtx->recoveryUnit()->onCommit(
- [](boost::optional<Timestamp>) { cluster_parameters::clearAllParameters(); });
+ ClusterServerParameterInitializer::get(opCtx)->clearAllParameters();
}
return {};
}
+void ClusterServerParameterOpObserver::postRenameCollection(
+ OperationContext* opCtx,
+ const NamespaceString& fromCollection,
+ const NamespaceString& toCollection,
+ const UUID& uuid,
+ const boost::optional<UUID>& dropTargetUUID,
+ bool stayTemp) {
+ if (isConfigNamespace(fromCollection)) {
+ // Same as collection dropped from a config point of view.
+ ClusterServerParameterInitializer::get(opCtx)->clearAllParameters();
+ }
+
+ if (isConfigNamespace(toCollection)) {
+ // Potentially many documents now set, perform full scan.
+ if (dropTargetUUID) {
+ // Possibly lost configurations in overwrite.
+ ClusterServerParameterInitializer::get(opCtx)->resynchronizeAllParametersFromDisk(
+ opCtx);
+ } else {
+ // Collection did not exist prior to rename.
+ ClusterServerParameterInitializer::get(opCtx)->initializeAllParametersFromDisk(opCtx);
+ }
+ }
+}
+
+void ClusterServerParameterOpObserver::onImportCollection(OperationContext* opCtx,
+ const UUID& importUUID,
+ const NamespaceString& nss,
+ long long numRecords,
+ long long dataSize,
+ const BSONObj& catalogEntry,
+ const BSONObj& storageMetadata,
+ bool isDryRun) {
+ if (!isDryRun && (numRecords > 0) && isConfigNamespace(nss)) {
+ // Something was imported, do a full collection scan to sync up.
+ // No need to apply rollback rules since nothing will have been deleted.
+ ClusterServerParameterInitializer::get(opCtx)->initializeAllParametersFromDisk(opCtx);
+ }
+}
+
void ClusterServerParameterOpObserver::_onReplicationRollback(OperationContext* opCtx,
const RollbackObserverInfo& rbInfo) {
if (rbInfo.rollbackNamespaces.count(NamespaceString::kClusterParametersNamespace)) {
// Some kind of rollback happend in the settings collection.
// Just reload from disk to be safe.
- // We can call resynchronize directly because onReplicationRollback is guaranteed to be
- // called from a state with no active WUOW and no database locks.
- cluster_parameters::resynchronizeAllParametersFromDisk(opCtx);
+ ClusterServerParameterInitializer::get(opCtx)->resynchronizeAllParametersFromDisk(opCtx);
}
}
diff --git a/src/mongo/idl/cluster_server_parameter_op_observer.h b/src/mongo/idl/cluster_server_parameter_op_observer.h
index 86bec6b61da..2ef05729e39 100644
--- a/src/mongo/idl/cluster_server_parameter_op_observer.h
+++ b/src/mongo/idl/cluster_server_parameter_op_observer.h
@@ -72,18 +72,12 @@ public:
const UUID& uuid,
std::uint64_t numRecords,
CollectionDropType dropType) final;
-
-private:
- void _onReplicationRollback(OperationContext* opCtx, const RollbackObserverInfo& rbInfo) final;
-
-public:
- // Remainder of operations are ignorable.
void postRenameCollection(OperationContext* opCtx,
const NamespaceString& fromCollection,
const NamespaceString& toCollection,
const UUID& uuid,
const boost::optional<UUID>& dropTargetUUID,
- bool stayTemp) final {}
+ bool stayTemp) final;
void onImportCollection(OperationContext* opCtx,
const UUID& importUUID,
const NamespaceString& nss,
@@ -91,7 +85,12 @@ public:
long long dataSize,
const BSONObj& catalogEntry,
const BSONObj& storageMetadata,
- bool isDryRun) final {}
+ bool isDryRun) final;
+
+ void _onReplicationRollback(OperationContext* opCtx, const RollbackObserverInfo& rbInfo) final;
+
+public:
+ // Remainder of operations are ignorable.
void onCreateIndex(OperationContext* opCtx,
const NamespaceString& nss,
@@ -213,10 +212,6 @@ public:
size_t numberOfPrePostImagesToWrite,
Date_t wallClockTime) final {}
- void onTransactionPrepareNonPrimary(OperationContext* opCtx,
- const std::vector<repl::OplogEntry>& statements,
- const repl::OpTime& prepareOpTime) final {}
-
void onTransactionAbort(OperationContext* opCtx,
boost::optional<OplogSlot> abortOplogEntryOpTime) final {}
diff --git a/src/mongo/idl/cluster_server_parameter_op_observer_test.cpp b/src/mongo/idl/cluster_server_parameter_op_observer_test.cpp
index 7553bfc191a..2ba82076bf2 100644
--- a/src/mongo/idl/cluster_server_parameter_op_observer_test.cpp
+++ b/src/mongo/idl/cluster_server_parameter_op_observer_test.cpp
@@ -31,9 +31,9 @@
#include "mongo/platform/basic.h"
-#include "mongo/db/catalog_raii.h"
-#include "mongo/idl/cluster_server_parameter_op_observer.h"
#include "mongo/idl/cluster_server_parameter_test_util.h"
+
+#include "mongo/idl/cluster_server_parameter_op_observer.h"
#include "mongo/logv2/log.h"
namespace mongo {
@@ -47,58 +47,60 @@ const std::vector<NamespaceString> kIgnoredNamespaces = {
class ClusterServerParameterOpObserverTest : public ClusterServerParameterTestBase {
public:
- void doInserts(const NamespaceString& nss,
- std::initializer_list<BSONObj> docs,
- bool commit = true) {
+ void doInserts(const NamespaceString& nss, std::initializer_list<BSONObj> docs) {
std::vector<InsertStatement> stmts;
std::transform(docs.begin(), docs.end(), std::back_inserter(stmts), [](auto doc) {
return InsertStatement(doc);
});
auto opCtx = cc().makeOperationContext();
- WriteUnitOfWork wuow(opCtx.get());
-
- AutoGetCollection autoColl(opCtx.get(), nss, MODE_IX);
observer.onInserts(
opCtx.get(), nss, UUID::gen(), stmts.cbegin(), stmts.cend(), false /* fromMigrate */);
- if (commit)
- wuow.commit();
}
- void doUpdate(const NamespaceString& nss, BSONObj updatedDoc, bool commit = true) {
+ void doUpdate(const NamespaceString& nss, BSONObj updatedDoc) {
// Actual UUID doesn't matter, just use any...
CollectionUpdateArgs updateArgs;
updateArgs.update = BSON("$set" << updatedDoc);
updateArgs.updatedDoc = updatedDoc;
OplogUpdateEntryArgs entryArgs(&updateArgs, nss, UUID::gen());
auto opCtx = cc().makeOperationContext();
- WriteUnitOfWork wuow(opCtx.get());
- AutoGetCollection autoColl(opCtx.get(), nss, MODE_IX);
observer.onUpdate(opCtx.get(), entryArgs);
- if (commit)
- wuow.commit();
}
- void doDelete(const NamespaceString& nss,
- BSONObj deletedDoc,
- bool includeDeletedDoc = true,
- bool commit = true) {
+ void doDelete(const NamespaceString& nss, BSONObj deletedDoc, bool includeDeletedDoc = true) {
auto opCtx = cc().makeOperationContext();
- WriteUnitOfWork wuow(opCtx.get());
- AutoGetCollection autoColl(opCtx.get(), nss, MODE_IX);
- observer.aboutToDelete(opCtx.get(), nss, UUID::gen(), deletedDoc);
+ auto uuid = UUID::gen();
+ observer.aboutToDelete(opCtx.get(), nss, uuid, deletedDoc);
OplogDeleteEntryArgs args;
args.deletedDoc = includeDeletedDoc ? &deletedDoc : nullptr;
- observer.onDelete(opCtx.get(), nss, UUID::gen(), 1 /* StmtId */, args);
- if (commit)
- wuow.commit();
+ observer.onDelete(opCtx.get(), nss, uuid, 1 /* StmtId */, args);
}
- void doDropDatabase(const std::string& dbname, bool commit = true) {
+ void doDropDatabase(StringData dbname) {
auto opCtx = cc().makeOperationContext();
- WriteUnitOfWork wuow(opCtx.get());
- observer.onDropDatabase(opCtx.get(), dbname);
- if (commit)
- wuow.commit();
+ observer.onDropDatabase(opCtx.get(), dbname.toString());
+ }
+
+ void doRenameCollection(const NamespaceString& fromColl, const NamespaceString& toColl) {
+ auto opCtx = cc().makeOperationContext();
+ observer.postRenameCollection(opCtx.get(),
+ fromColl,
+ toColl,
+ UUID::gen(),
+ boost::none /* targetUUID */,
+ false /* stayTemp */);
+ }
+
+ void doImportCollection(const NamespaceString& nss) {
+ auto opCtx = cc().makeOperationContext();
+ observer.onImportCollection(opCtx.get(),
+ UUID::gen(),
+ nss,
+ 10 /* num records */,
+ 1 << 20 /* data size */,
+ BSONObj() /* catalogEntry */,
+ BSONObj() /* storageMetadata */,
+ false /* isDryRun */);
}
void doReplicationRollback(const std::vector<NamespaceString>& namespaces) {
@@ -163,28 +165,6 @@ public:
assertIgnored(NamespaceString::kClusterParametersNamespace, fn);
}
- void assertParameterState(int line,
- int intVal,
- StringData strVal,
- boost::optional<LogicalTime> cpt = boost::none) {
- auto* sp = ServerParameterSet::getClusterParameterSet()
- ->get<IDLServerParameterWithStorage<ServerParameterType::kClusterWide,
- ClusterServerParameterTest>>(kCSPTest);
- ;
- try {
- if (cpt) {
- ASSERT_EQ(sp->getClusterParameterTime(), *cpt);
- }
-
- ClusterServerParameterTest cspTest = sp->getValue();
- ASSERT_EQ(cspTest.getIntValue(), intVal);
- ASSERT_EQ(cspTest.getStrValue(), strVal);
- } catch (...) {
- LOGV2_ERROR(6887700, "ASSERT_PARAMETER_STATE failed", "line"_attr = line);
- throw;
- }
- }
-
protected:
ClusterServerParameterOpObserver observer;
};
@@ -328,12 +308,12 @@ TEST_F(ClusterServerParameterOpObserverTest, onDropDatabase) {
assertIgnoredOtherNamespaces([this](const auto& nss) {
const auto dbname = nss.db();
if (dbname != kConfigDB) {
- doDropDatabase(dbname.toString());
+ doDropDatabase(dbname);
}
});
// Actually drop the config DB.
- doDropDatabase(kConfigDB.toString());
+ doDropDatabase(kConfigDB);
auto* sp = ServerParameterSet::getClusterParameterSet()
->get<IDLServerParameterWithStorage<ServerParameterType::kClusterWide,
@@ -345,12 +325,63 @@ TEST_F(ClusterServerParameterOpObserverTest, onDropDatabase) {
ASSERT_EQ(cspTest.getStrValue(), kDefaultStrValue);
}
+TEST_F(ClusterServerParameterOpObserverTest, onRenameCollection) {
+ initializeState();
+
+ const NamespaceString kTestFoo("test", "foo");
+ // Rename ignorable collections.
+ assertIgnoredOtherNamespaces([&](const auto& nss) { doRenameCollection(nss, kTestFoo); });
+ assertIgnoredOtherNamespaces([&](const auto& nss) { doRenameCollection(kTestFoo, nss); });
+
+ auto* sp = ServerParameterSet::getClusterParameterSet()
+ ->get<IDLServerParameterWithStorage<ServerParameterType::kClusterWide,
+ ClusterServerParameterTest>>(kCSPTest);
+ ASSERT(sp != nullptr);
+
+ // These renames "work" despite not mutating durable state
+ // since the rename away doesn't require a rescan.
+
+ // Rename away (and reset to default)
+ doRenameCollection(NamespaceString::kClusterParametersNamespace, kTestFoo);
+ ClusterServerParameterTest cspTest = sp->getValue();
+ ASSERT_EQ(cspTest.getIntValue(), kDefaultIntValue);
+ ASSERT_EQ(cspTest.getStrValue(), kDefaultStrValue);
+
+ // Rename in (and restore to initialized state)
+ doRenameCollection(kTestFoo, NamespaceString::kClusterParametersNamespace);
+ cspTest = sp->getValue();
+ ASSERT_EQ(cspTest.getIntValue(), kInitialIntValue);
+ ASSERT_EQ(cspTest.getStrValue(), kInitialStrValue);
+}
+
+TEST_F(ClusterServerParameterOpObserverTest, onImportCollection) {
+ initializeState();
+
+ const NamespaceString kTestFoo("test", "foo");
+ // Import ignorable collections.
+ assertIgnoredOtherNamespaces([&](const auto& nss) { doImportCollection(nss); });
+
+ auto* sp = ServerParameterSet::getClusterParameterSet()
+ ->get<IDLServerParameterWithStorage<ServerParameterType::kClusterWide,
+ ClusterServerParameterTest>>(kCSPTest);
+ ASSERT(sp != nullptr);
+
+ // Import the collection (rescan).
+ auto doc =
+ makeClusterParametersDoc(LogicalTime(Timestamp(time(nullptr))), 333, "onImportCollection");
+ upsert(doc);
+ doImportCollection(NamespaceString::kClusterParametersNamespace);
+ ClusterServerParameterTest cspTest = sp->getValue();
+ ASSERT_EQ(cspTest.getIntValue(), 333);
+ ASSERT_EQ(cspTest.getStrValue(), "onImportCollection");
+}
+
TEST_F(ClusterServerParameterOpObserverTest, onReplicationRollback) {
initializeState();
const NamespaceString kTestFoo("test", "foo");
// Import ignorable collections.
- assertIgnoredOtherNamespaces([&](const auto& nss) { doReplicationRollback({nss}); });
+ assertIgnoredOtherNamespaces([&](const auto& nss) { doImportCollection(nss); });
auto* sp = ServerParameterSet::getClusterParameterSet()
->get<IDLServerParameterWithStorage<ServerParameterType::kClusterWide,
@@ -381,37 +412,5 @@ TEST_F(ClusterServerParameterOpObserverTest, onReplicationRollback) {
ASSERT_EQ(cspTest.getStrValue(), kDefaultStrValue);
}
-#define ASSERT_PARAMETER_STATE(...) assertParameterState(__LINE__, __VA_ARGS__)
-
-TEST_F(ClusterServerParameterOpObserverTest, abortsAfterObservation) {
-
- const auto initialDoc = initializeState();
-
- doInserts(NamespaceString::kClusterParametersNamespace,
- {makeClusterParametersDoc(LogicalTime(Timestamp(12345678)), 123, "abc")},
- false /* commit */);
-
- ASSERT_PARAMETER_STATE(kInitialIntValue, kInitialStrValue);
-
- doUpdate(NamespaceString::kClusterParametersNamespace,
- {makeClusterParametersDoc(LogicalTime(Timestamp(87654321)), 321, "cba")},
- false /* commit */);
-
- ASSERT_PARAMETER_STATE(kInitialIntValue, kInitialStrValue);
-
- doDelete(NamespaceString::kClusterParametersNamespace,
- initialDoc,
- true /* includeDeletedDoc */,
- false /* commit */);
-
- ASSERT_PARAMETER_STATE(kInitialIntValue, kInitialStrValue);
-
- doDropDatabase(kConfigDB.toString(), false /* commit */);
-
- ASSERT_PARAMETER_STATE(kInitialIntValue, kInitialStrValue);
-}
-
-#undef ASSERT_PARAMETER_STATE
-
} // namespace
} // namespace mongo
diff --git a/src/mongo/idl/server_parameter_test_util.h b/src/mongo/idl/server_parameter_test_util.h
index f7e2ae31834..566489dd1a9 100644
--- a/src/mongo/idl/server_parameter_test_util.h
+++ b/src/mongo/idl/server_parameter_test_util.h
@@ -36,59 +36,38 @@
namespace mongo {
/**
- * Test-only class that sets a server parameter to the specified value and allows
- * resetting after the test completes.
+ * Test-only RAII type that allows to set a server parameter value during the execution of a
+ * unit test, or part of a unit test, and resets it to the original value on destruction.
*/
-class ServerParameterControllerForTest {
+class RAIIServerParameterControllerForTest {
public:
/**
* Constructor setting the server parameter to the specified value.
*/
template <typename T>
- ServerParameterControllerForTest(const std::string& name, T value)
+ RAIIServerParameterControllerForTest(const std::string& name, T value)
: _serverParam(ServerParameterSet::getNodeParameterSet()->get(name)) {
- // Save the old value.
+ // Save the old value
BSONObjBuilder bob;
_serverParam->appendSupportingRoundtrip(nullptr, bob, name);
_oldValue = bob.obj();
- // Set server param to the new value.
+ // Set to the new value
uassertStatusOK(_serverParam->set(BSON(name << value).firstElement()));
}
- void reset() {
- // Reset to the old value.
- auto elem = _oldValue.firstElement();
- uassertStatusOK(_serverParam->set(elem));
- }
-
-private:
- ServerParameter* _serverParam;
- BSONObj _oldValue;
-};
-
-/**
- * Test-only RAII type that wraps ServerParameterControllerForTest. Upon destruction, the server
- * parameter will be set to its original value.
- */
-class RAIIServerParameterControllerForTest {
-public:
- /**
- * Constructor setting the server parameter to the specified value.
- */
- template <typename T>
- RAIIServerParameterControllerForTest(const std::string& name, T value)
- : _serverParamController(ServerParameterControllerForTest(name, value)) {}
-
/**
* Destructor resetting the server parameter to the original value.
*/
~RAIIServerParameterControllerForTest() {
- _serverParamController.reset();
+ // Reset to the old value
+ auto elem = _oldValue.firstElement();
+ uassertStatusOK(_serverParam->set(elem));
}
private:
- ServerParameterControllerForTest _serverParamController;
+ ServerParameter* _serverParam;
+ BSONObj _oldValue;
};
} // namespace mongo