diff options
Diffstat (limited to 'src/mongo/s')
-rw-r--r-- | src/mongo/s/catalog/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/s/catalog/sharding_catalog_client.h | 27 | ||||
-rw-r--r-- | src/mongo/s/catalog/sharding_catalog_client_impl.cpp | 125 | ||||
-rw-r--r-- | src/mongo/s/catalog/sharding_catalog_client_impl.h | 45 | ||||
-rw-r--r-- | src/mongo/s/catalog/sharding_catalog_client_mock.cpp | 15 | ||||
-rw-r--r-- | src/mongo/s/catalog/sharding_catalog_client_mock.h | 11 | ||||
-rw-r--r-- | src/mongo/s/catalog/sharding_catalog_log_change_test.cpp | 226 | ||||
-rw-r--r-- | src/mongo/s/catalog/type_changelog.cpp | 16 | ||||
-rw-r--r-- | src/mongo/s/catalog/type_changelog.h | 10 | ||||
-rw-r--r-- | src/mongo/s/catalog/type_changelog_test.cpp | 60 |
10 files changed, 85 insertions, 451 deletions
diff --git a/src/mongo/s/catalog/SConscript b/src/mongo/s/catalog/SConscript index 88d3a3eb090..f37bf3fefc6 100644 --- a/src/mongo/s/catalog/SConscript +++ b/src/mongo/s/catalog/SConscript @@ -138,7 +138,6 @@ env.CppUnitTest( env.CppUnitTest( target='sharding_catalog_client_test', source=[ - 'sharding_catalog_log_change_test.cpp', 'sharding_catalog_test.cpp', 'sharding_catalog_write_retry_test.cpp', ], diff --git a/src/mongo/s/catalog/sharding_catalog_client.h b/src/mongo/s/catalog/sharding_catalog_client.h index aa68fcc0ad1..219a623939e 100644 --- a/src/mongo/s/catalog/sharding_catalog_client.h +++ b/src/mongo/s/catalog/sharding_catalog_client.h @@ -270,33 +270,6 @@ public: repl::ReadConcernLevel readConcern) = 0; /** - * Writes a diagnostic event to the action log. - */ - virtual Status logAction(OperationContext* opCtx, - const std::string& what, - const std::string& ns, - const BSONObj& detail) = 0; - - /** - * Writes a diagnostic event to the change log. - */ - virtual Status logChangeChecked(OperationContext* opCtx, - const std::string& what, - const std::string& ns, - const BSONObj& detail, - const WriteConcernOptions& writeConcern) = 0; - - void logChange(OperationContext* const opCtx, - const std::string& what, - const std::string& ns, - const BSONObj& detail, - const WriteConcernOptions& writeConcern) { - // It is safe to ignore the results of `logChangeChecked` in many cases, as the - // failure to log a change is often of no consequence. - logChangeChecked(opCtx, what, ns, detail, writeConcern).ignore(); - } - - /** * Reads global sharding settings from the confing.settings collection. The key parameter is * used as the _id of the respective setting document. * diff --git a/src/mongo/s/catalog/sharding_catalog_client_impl.cpp b/src/mongo/s/catalog/sharding_catalog_client_impl.cpp index e50149d3f15..048656f4426 100644 --- a/src/mongo/s/catalog/sharding_catalog_client_impl.cpp +++ b/src/mongo/s/catalog/sharding_catalog_client_impl.cpp @@ -53,7 +53,6 @@ #include "mongo/rpc/metadata/repl_set_metadata.h" #include "mongo/s/catalog/config_server_version.h" #include "mongo/s/catalog/dist_lock_manager.h" -#include "mongo/s/catalog/type_changelog.h" #include "mongo/s/catalog/type_chunk.h" #include "mongo/s/catalog/type_collection.h" #include "mongo/s/catalog/type_config_version.h" @@ -95,12 +94,6 @@ const ReadPreferenceSetting kConfigPrimaryPreferredSelector(ReadPreference::Prim const int kMaxReadRetry = 3; const int kMaxWriteRetry = 3; -const std::string kActionLogCollectionName("actionlog"); -const int kActionLogCollectionSizeMB = 20 * 1024 * 1024; - -const std::string kChangeLogCollectionName("changelog"); -const int kChangeLogCollectionSizeMB = 200 * 1024 * 1024; - const NamespaceString kSettingsNamespace("config", "settings"); void toBatchError(const Status& status, BatchedCommandResponse* response) { @@ -153,87 +146,6 @@ Status ShardingCatalogClientImpl::updateShardingCatalogEntryForCollection( return status.getStatus().withContext(str::stream() << "Collection metadata write failed"); } -Status ShardingCatalogClientImpl::logAction(OperationContext* opCtx, - const std::string& what, - const std::string& ns, - const BSONObj& detail) { - if (_actionLogCollectionCreated.load() == 0) { - Status result = _createCappedConfigCollection(opCtx, - kActionLogCollectionName, - kActionLogCollectionSizeMB, - ShardingCatalogClient::kMajorityWriteConcern); - if (result.isOK()) { - _actionLogCollectionCreated.store(1); - } else { - log() << "couldn't create config.actionlog collection:" << causedBy(result); - return result; - } - } - - return _log(opCtx, - kActionLogCollectionName, - what, - ns, - detail, - ShardingCatalogClient::kMajorityWriteConcern); -} - -Status ShardingCatalogClientImpl::logChangeChecked(OperationContext* opCtx, - const std::string& what, - const std::string& ns, - const BSONObj& detail, - const WriteConcernOptions& writeConcern) { - invariant(serverGlobalParams.clusterRole == ClusterRole::ConfigServer || - writeConcern.wMode == WriteConcernOptions::kMajority); - if (_changeLogCollectionCreated.load() == 0) { - Status result = _createCappedConfigCollection( - opCtx, kChangeLogCollectionName, kChangeLogCollectionSizeMB, writeConcern); - if (result.isOK()) { - _changeLogCollectionCreated.store(1); - } else { - log() << "couldn't create config.changelog collection:" << causedBy(result); - return result; - } - } - - return _log(opCtx, kChangeLogCollectionName, what, ns, detail, writeConcern); -} - -Status ShardingCatalogClientImpl::_log(OperationContext* opCtx, - const StringData& logCollName, - const std::string& what, - const std::string& operationNS, - const BSONObj& detail, - const WriteConcernOptions& writeConcern) { - Date_t now = Grid::get(opCtx)->getNetwork()->now(); - const std::string serverName = str::stream() << Grid::get(opCtx)->getNetwork()->getHostName() - << ":" << serverGlobalParams.port; - const std::string changeId = str::stream() << serverName << "-" << now.toString() << "-" - << OID::gen(); - - ChangeLogType changeLog; - changeLog.setChangeId(changeId); - changeLog.setServer(serverName); - changeLog.setClientAddr(opCtx->getClient()->clientAddress(true)); - changeLog.setTime(now); - changeLog.setNS(operationNS); - changeLog.setWhat(what); - changeLog.setDetails(detail); - - BSONObj changeLogBSON = changeLog.toBSON(); - log() << "about to log metadata event into " << logCollName << ": " << redact(changeLogBSON); - - const NamespaceString nss("config", logCollName); - Status result = insertConfigDocument(opCtx, nss, changeLogBSON, writeConcern); - - if (!result.isOK()) { - warning() << "Error encountered while logging config change with ID [" << changeId - << "] into collection " << logCollName << ": " << redact(result); - } - - return result; -} - StatusWith<repl::OpTimeWith<DatabaseType>> ShardingCatalogClientImpl::getDatabase( OperationContext* opCtx, const std::string& dbName, repl::ReadConcernLevel readConcernLevel) { if (!NamespaceString::validDBName(dbName, NamespaceString::DollarInDbNameBehavior::Allow)) { @@ -977,43 +889,6 @@ Status ShardingCatalogClientImpl::removeConfigDocuments(OperationContext* opCtx, return response.toStatus(); } -Status ShardingCatalogClientImpl::_createCappedConfigCollection( - OperationContext* opCtx, - StringData collName, - int cappedSize, - const WriteConcernOptions& writeConcern) { - BSONObj createCmd = BSON("create" << collName << "capped" << true << "size" << cappedSize - << WriteConcernOptions::kWriteConcernField - << writeConcern.toBSON()); - - auto result = - Grid::get(opCtx)->shardRegistry()->getConfigShard()->runCommandWithFixedRetryAttempts( - opCtx, - ReadPreferenceSetting{ReadPreference::PrimaryOnly}, - "config", - createCmd, - Shard::kDefaultConfigCommandTimeout, - Shard::RetryPolicy::kIdempotent); - - if (!result.isOK()) { - return result.getStatus(); - } - - if (!result.getValue().commandStatus.isOK()) { - if (result.getValue().commandStatus == ErrorCodes::NamespaceExists) { - if (result.getValue().writeConcernStatus.isOK()) { - return Status::OK(); - } else { - return result.getValue().writeConcernStatus; - } - } else { - return result.getValue().commandStatus; - } - } - - return result.getValue().writeConcernStatus; -} - StatusWith<repl::OpTimeWith<vector<BSONObj>>> ShardingCatalogClientImpl::_exhaustiveFindOnConfig( OperationContext* opCtx, const ReadPreferenceSetting& readPref, diff --git a/src/mongo/s/catalog/sharding_catalog_client_impl.h b/src/mongo/s/catalog/sharding_catalog_client_impl.h index c6f48bb8de5..1e60cede5ee 100644 --- a/src/mongo/s/catalog/sharding_catalog_client_impl.h +++ b/src/mongo/s/catalog/sharding_catalog_client_impl.h @@ -73,17 +73,6 @@ public: void shutDown(OperationContext* opCtx) override; - Status logAction(OperationContext* opCtx, - const std::string& what, - const std::string& ns, - const BSONObj& detail) override; - - Status logChangeChecked(OperationContext* opCtx, - const std::string& what, - const std::string& ns, - const BSONObj& detail, - const WriteConcernOptions& writeConcern) override; - StatusWith<repl::OpTimeWith<DatabaseType>> getDatabase( OperationContext* opCtx, const std::string& dbName, @@ -195,14 +184,6 @@ private: bool upsert, const WriteConcernOptions& writeConcern); - /** - * Creates the specified collection name in the config database. - */ - Status _createCappedConfigCollection(OperationContext* opCtx, - StringData collName, - int cappedSize, - const WriteConcernOptions& writeConcern); - StatusWith<repl::OpTimeWith<std::vector<BSONObj>>> _exhaustiveFindOnConfig( OperationContext* opCtx, const ReadPreferenceSetting& readPref, @@ -222,32 +203,12 @@ private: const ReadPreferenceSetting& readPref, repl::ReadConcernLevel readConcernLevel); - /** - * Best effort method, which logs diagnostic events on the config server. If the config server - * write fails for any reason a warning will be written to the local service log and the method - * will return a failed status. - * - * @param opCtx Operation context in which the call is running - * @param logCollName Which config collection to write to (excluding the database name) - * @param what E.g. "split", "migrate" (not interpreted) - * @param operationNS To which collection the metadata change is being applied (not interpreted) - * @param detail Additional info about the metadata change (not interpreted) - * @param writeConcern Write concern options to use for logging - */ - Status _log(OperationContext* opCtx, - const StringData& logCollName, - const std::string& what, - const std::string& operationNSS, - const BSONObj& detail, - const WriteConcernOptions& writeConcern); - // // All member variables are labeled with one of the following codes indicating the // synchronization rules for accessing them. // // (M) Must hold _mutex for access. // (R) Read only, can only be written during initialization. - // (S) Self-synchronizing; access in any way from any context. // stdx::mutex _mutex; @@ -260,12 +221,6 @@ private: // True if startup() has been called. bool _started = false; // (M) - - // Whether the logAction call should attempt to create the actionlog collection - AtomicInt32 _actionLogCollectionCreated{0}; // (S) - - // Whether the logChange call should attempt to create the changelog collection - AtomicInt32 _changeLogCollectionCreated{0}; // (S) }; } // namespace mongo diff --git a/src/mongo/s/catalog/sharding_catalog_client_mock.cpp b/src/mongo/s/catalog/sharding_catalog_client_mock.cpp index 613ff1a5b68..d415641f6c0 100644 --- a/src/mongo/s/catalog/sharding_catalog_client_mock.cpp +++ b/src/mongo/s/catalog/sharding_catalog_client_mock.cpp @@ -143,21 +143,6 @@ Status ShardingCatalogClientMock::applyChunkOpsDeprecated(OperationContext* opCt return {ErrorCodes::InternalError, "Method not implemented"}; } -Status ShardingCatalogClientMock::logAction(OperationContext* opCtx, - const std::string& what, - const std::string& ns, - const BSONObj& detail) { - return {ErrorCodes::InternalError, "Method not implemented"}; -} - -Status ShardingCatalogClientMock::logChangeChecked(OperationContext* opCtx, - const std::string& what, - const std::string& ns, - const BSONObj& detail, - const WriteConcernOptions& writeConcern) { - return {ErrorCodes::InternalError, "Method not implemented"}; -} - StatusWith<BSONObj> ShardingCatalogClientMock::getGlobalSettings(OperationContext* opCtx, StringData key) { return {ErrorCodes::InternalError, "Method not implemented"}; diff --git a/src/mongo/s/catalog/sharding_catalog_client_mock.h b/src/mongo/s/catalog/sharding_catalog_client_mock.h index 9301f8dd034..3ab56cd9a6b 100644 --- a/src/mongo/s/catalog/sharding_catalog_client_mock.h +++ b/src/mongo/s/catalog/sharding_catalog_client_mock.h @@ -103,17 +103,6 @@ public: const WriteConcernOptions& writeConcern, repl::ReadConcernLevel readConcern) override; - Status logAction(OperationContext* opCtx, - const std::string& what, - const std::string& ns, - const BSONObj& detail) override; - - Status logChangeChecked(OperationContext* opCtx, - const std::string& what, - const std::string& ns, - const BSONObj& detail, - const WriteConcernOptions& writeConcern) override; - StatusWith<BSONObj> getGlobalSettings(OperationContext* opCtx, StringData key) override; StatusWith<VersionType> getConfigVersion(OperationContext* opCtx, diff --git a/src/mongo/s/catalog/sharding_catalog_log_change_test.cpp b/src/mongo/s/catalog/sharding_catalog_log_change_test.cpp deleted file mode 100644 index f7d2688a368..00000000000 --- a/src/mongo/s/catalog/sharding_catalog_log_change_test.cpp +++ /dev/null @@ -1,226 +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 <vector> - -#include "mongo/client/remote_command_targeter_mock.h" -#include "mongo/db/commands.h" -#include "mongo/executor/network_interface_mock.h" -#include "mongo/executor/task_executor.h" -#include "mongo/s/catalog/sharding_catalog_client.h" -#include "mongo/s/client/shard_registry.h" -#include "mongo/s/sharding_router_test_fixture.h" -#include "mongo/stdx/chrono.h" -#include "mongo/stdx/future.h" -#include "mongo/util/log.h" -#include "mongo/util/mongoutils/str.h" -#include "mongo/util/text.h" - -namespace mongo { -namespace { - -using executor::NetworkInterfaceMock; -using executor::TaskExecutor; -using stdx::async; -using unittest::assertGet; - -const Seconds kFutureTimeout{5}; -const HostAndPort configHost{"TestHost1"}; - -class InfoLoggingTest : public ShardingTestFixture { -public: - enum CollType { ActionLog, ChangeLog }; - - InfoLoggingTest(CollType configCollType, int cappedSize) - : _configCollType(configCollType), _cappedSize(cappedSize) {} - - void setUp() override { - ShardingTestFixture::setUp(); - - configTargeter()->setFindHostReturnValue(configHost); - } - -protected: - void noRetryAfterSuccessfulCreate() { - auto future = launchAsync([this] { - log("moved a chunk", "foo.bar", BSON("min" << 3 << "max" << 4)).transitional_ignore(); - }); - - expectConfigCollectionCreate(configHost, getConfigCollName(), _cappedSize, BSON("ok" << 1)); - expectConfigCollectionInsert(configHost, - getConfigCollName(), - network()->now(), - "moved a chunk", - "foo.bar", - BSON("min" << 3 << "max" << 4)); - - // Now wait for the logChange call to return - future.timed_get(kFutureTimeout); - - // Now log another change and confirm that we don't re-attempt to create the collection - future = launchAsync([this] { - log("moved a second chunk", "foo.bar", BSON("min" << 4 << "max" << 5)) - .transitional_ignore(); - }); - - expectConfigCollectionInsert(configHost, - getConfigCollName(), - network()->now(), - "moved a second chunk", - "foo.bar", - BSON("min" << 4 << "max" << 5)); - - // Now wait for the logChange call to return - future.timed_get(kFutureTimeout); - } - - void noRetryCreateIfAlreadyExists() { - auto future = launchAsync([this] { - log("moved a chunk", "foo.bar", BSON("min" << 3 << "max" << 4)).transitional_ignore(); - }); - - BSONObjBuilder createResponseBuilder; - CommandHelpers::appendCommandStatusNoThrow( - createResponseBuilder, Status(ErrorCodes::NamespaceExists, "coll already exists")); - expectConfigCollectionCreate( - configHost, getConfigCollName(), _cappedSize, createResponseBuilder.obj()); - expectConfigCollectionInsert(configHost, - getConfigCollName(), - network()->now(), - "moved a chunk", - "foo.bar", - BSON("min" << 3 << "max" << 4)); - - // Now wait for the logAction call to return - future.timed_get(kFutureTimeout); - - // Now log another change and confirm that we don't re-attempt to create the collection - future = launchAsync([this] { - log("moved a second chunk", "foo.bar", BSON("min" << 4 << "max" << 5)) - .transitional_ignore(); - }); - - expectConfigCollectionInsert(configHost, - getConfigCollName(), - network()->now(), - "moved a second chunk", - "foo.bar", - BSON("min" << 4 << "max" << 5)); - - // Now wait for the logChange call to return - future.timed_get(kFutureTimeout); - } - - void createFailure() { - auto future = launchAsync([this] { - log("moved a chunk", "foo.bar", BSON("min" << 3 << "max" << 4)).transitional_ignore(); - }); - - BSONObjBuilder createResponseBuilder; - CommandHelpers::appendCommandStatusNoThrow( - createResponseBuilder, Status(ErrorCodes::ExceededTimeLimit, "operation timed out")); - expectConfigCollectionCreate( - configHost, getConfigCollName(), _cappedSize, createResponseBuilder.obj()); - - // Now wait for the logAction call to return - future.timed_get(kFutureTimeout); - - // Now log another change and confirm that we *do* attempt to create the collection - future = launchAsync([this] { - log("moved a second chunk", "foo.bar", BSON("min" << 4 << "max" << 5)) - .transitional_ignore(); - }); - - expectConfigCollectionCreate(configHost, getConfigCollName(), _cappedSize, BSON("ok" << 1)); - expectConfigCollectionInsert(configHost, - getConfigCollName(), - network()->now(), - "moved a second chunk", - "foo.bar", - BSON("min" << 4 << "max" << 5)); - - // Now wait for the logChange call to return - future.timed_get(kFutureTimeout); - } - - std::string getConfigCollName() const { - return (_configCollType == ChangeLog ? "changelog" : "actionlog"); - } - - Status log(const std::string& what, const std::string& ns, const BSONObj& detail) { - if (_configCollType == ChangeLog) { - return catalogClient()->logChangeChecked( - operationContext(), what, ns, detail, ShardingCatalogClient::kMajorityWriteConcern); - } else { - return catalogClient()->logAction(operationContext(), what, ns, detail); - } - } - - const CollType _configCollType; - const int _cappedSize; -}; - -class ActionLogTest : public InfoLoggingTest { -public: - ActionLogTest() : InfoLoggingTest(ActionLog, 20 * 1024 * 1024) {} -}; - -class ChangeLogTest : public InfoLoggingTest { -public: - ChangeLogTest() : InfoLoggingTest(ChangeLog, 200 * 1024 * 1024) {} -}; - -TEST_F(ActionLogTest, NoRetryAfterSuccessfulCreate) { - noRetryAfterSuccessfulCreate(); -} -TEST_F(ChangeLogTest, NoRetryAfterSuccessfulCreate) { - noRetryAfterSuccessfulCreate(); -} - -TEST_F(ActionLogTest, NoRetryCreateIfAlreadyExists) { - noRetryCreateIfAlreadyExists(); -} -TEST_F(ChangeLogTest, NoRetryCreateIfAlreadyExists) { - noRetryCreateIfAlreadyExists(); -} - -TEST_F(ActionLogTest, CreateFailure) { - createFailure(); -} -TEST_F(ChangeLogTest, CreateFailure) { - createFailure(); -} - -} // namespace -} // namespace mongo diff --git a/src/mongo/s/catalog/type_changelog.cpp b/src/mongo/s/catalog/type_changelog.cpp index 6d15de7db14..2829027d451 100644 --- a/src/mongo/s/catalog/type_changelog.cpp +++ b/src/mongo/s/catalog/type_changelog.cpp @@ -43,6 +43,7 @@ namespace mongo { const BSONField<std::string> ChangeLogType::changeId("_id"); const BSONField<std::string> ChangeLogType::server("server"); +const BSONField<std::string> ChangeLogType::shard("shard"); const BSONField<std::string> ChangeLogType::clientAddr("clientAddr"); const BSONField<Date_t> ChangeLogType::time("time"); const BSONField<std::string> ChangeLogType::what("what"); @@ -69,6 +70,15 @@ StatusWith<ChangeLogType> ChangeLogType::fromBSON(const BSONObj& source) { } { + std::string changeLogShard; + Status status = + bsonExtractStringFieldWithDefault(source, shard.name(), "", &changeLogShard); + if (!status.isOK()) + return status; + changeLog._shard = changeLogShard; + } + + { std::string changeLogClientAddr; Status status = bsonExtractStringField(source, clientAddr.name(), &changeLogClientAddr); if (!status.isOK()) @@ -142,6 +152,8 @@ BSONObj ChangeLogType::toBSON() const { builder.append(changeId.name(), getChangeId()); if (_server) builder.append(server.name(), getServer()); + if (_shard) + builder.append(shard.name(), getShard()); if (_clientAddr) builder.append(clientAddr.name(), getClientAddr()); if (_time) @@ -164,6 +176,10 @@ void ChangeLogType::setServer(const std::string& server) { _server = server; } +void ChangeLogType::setShard(const std::string& shard) { + _shard = shard; +} + void ChangeLogType::setClientAddr(const std::string& clientAddr) { _clientAddr = clientAddr; } diff --git a/src/mongo/s/catalog/type_changelog.h b/src/mongo/s/catalog/type_changelog.h index 9f25e57745f..d7b00d2b840 100644 --- a/src/mongo/s/catalog/type_changelog.h +++ b/src/mongo/s/catalog/type_changelog.h @@ -48,6 +48,7 @@ public: // Field names and types in the changelog collection type. static const BSONField<std::string> changeId; static const BSONField<std::string> server; + static const BSONField<std::string> shard; static const BSONField<std::string> clientAddr; static const BSONField<Date_t> time; static const BSONField<std::string> what; @@ -86,6 +87,11 @@ public: } void setServer(const std::string& server); + const std::string& getShard() const { + return _shard.get(); + } + void setShard(const std::string& shard); + const std::string& getClientAddr() const { return _clientAddr.get(); } @@ -116,8 +122,10 @@ private: // (M) id for this change "<hostname>-<current_time>-<increment>" boost::optional<std::string> _changeId; - // (M) hostname of server that we are making the change on. Does not include port. + // (M) hostname of server that we are making the change on. boost::optional<std::string> _server; + // (O) id of shard making the change, or "config" for configSvrs + boost::optional<std::string> _shard; // (M) hostname:port of the client that made this change boost::optional<std::string> _clientAddr; // (M) time this change was made diff --git a/src/mongo/s/catalog/type_changelog_test.cpp b/src/mongo/s/catalog/type_changelog_test.cpp index da5fec257bd..e30c82d0d86 100644 --- a/src/mongo/s/catalog/type_changelog_test.cpp +++ b/src/mongo/s/catalog/type_changelog_test.cpp @@ -48,6 +48,7 @@ TEST(ChangeLogType, Empty) { TEST(ChangeLogType, Valid) { BSONObj obj = BSON(ChangeLogType::changeId("host.local-2012-11-21T19:14:10-8") << ChangeLogType::server("host.local") + << ChangeLogType::shard("shardname") << ChangeLogType::clientAddr("192.168.0.189:51128") << ChangeLogType::time(Date_t::fromMillisSinceEpoch(1)) << ChangeLogType::what("split") @@ -62,6 +63,7 @@ TEST(ChangeLogType, Valid) { ASSERT_EQUALS(logEntry.getChangeId(), "host.local-2012-11-21T19:14:10-8"); ASSERT_EQUALS(logEntry.getServer(), "host.local"); + ASSERT_EQUALS(logEntry.getShard(), "shardname"); ASSERT_EQUALS(logEntry.getClientAddr(), "192.168.0.189:51128"); ASSERT_EQUALS(logEntry.getTime(), Date_t::fromMillisSinceEpoch(1)); ASSERT_EQUALS(logEntry.getWhat(), "split"); @@ -73,6 +75,7 @@ TEST(ChangeLogType, Valid) { TEST(ChangeLogType, MissingChangeId) { BSONObj obj = BSON(ChangeLogType::server("host.local") + << ChangeLogType::shard("shardname") << ChangeLogType::clientAddr("192.168.0.189:51128") << ChangeLogType::time(Date_t::fromMillisSinceEpoch(1)) << ChangeLogType::what("split") @@ -86,6 +89,7 @@ TEST(ChangeLogType, MissingChangeId) { TEST(ChangeLogType, MissingServer) { BSONObj obj = BSON(ChangeLogType::changeId("host.local-2012-11-21T19:14:10-8") + << ChangeLogType::shard("shardname") << ChangeLogType::clientAddr("192.168.0.189:51128") << ChangeLogType::time(Date_t::fromMillisSinceEpoch(1)) << ChangeLogType::what("split") @@ -100,6 +104,7 @@ TEST(ChangeLogType, MissingServer) { TEST(ChangeLogType, MissingClientAddr) { BSONObj obj = BSON(ChangeLogType::changeId("host.local-2012-11-21T19:14:10-8") << ChangeLogType::server("host.local") + << ChangeLogType::shard("shardname") << ChangeLogType::time(Date_t::fromMillisSinceEpoch(1)) << ChangeLogType::what("split") << ChangeLogType::ns("test.test") @@ -113,6 +118,7 @@ TEST(ChangeLogType, MissingClientAddr) { TEST(ChangeLogType, MissingTime) { BSONObj obj = BSON(ChangeLogType::changeId("host.local-2012-11-21T19:14:10-8") << ChangeLogType::server("host.local") + << ChangeLogType::shard("shardname") << ChangeLogType::clientAddr("192.168.0.189:51128") << ChangeLogType::what("split") << ChangeLogType::ns("test.test") @@ -126,6 +132,7 @@ TEST(ChangeLogType, MissingTime) { TEST(ChangeLogType, MissingWhat) { BSONObj obj = BSON(ChangeLogType::changeId("host.local-2012-11-21T19:14:10-8") << ChangeLogType::server("host.local") + << ChangeLogType::shard("shardname") << ChangeLogType::clientAddr("192.168.0.189:51128") << ChangeLogType::time(Date_t::fromMillisSinceEpoch(1)) << ChangeLogType::ns("test.test") @@ -136,9 +143,36 @@ TEST(ChangeLogType, MissingWhat) { ASSERT_EQ(ErrorCodes::NoSuchKey, changeLogResult.getStatus()); } +TEST(ChangeLogType, MissingNS) { + BSONObj obj = BSON(ChangeLogType::changeId("host.local-2012-11-21T19:14:10-8") + << ChangeLogType::server("host.local") + << ChangeLogType::shard("shardname") + << ChangeLogType::clientAddr("192.168.0.189:51128") + << ChangeLogType::time(Date_t::fromMillisSinceEpoch(1)) + << ChangeLogType::what("split") + << ChangeLogType::details(BSON("dummy" + << "info"))); + + auto changeLogResult = ChangeLogType::fromBSON(obj); + ASSERT_OK(changeLogResult.getStatus()); + ChangeLogType& logEntry = changeLogResult.getValue(); + ASSERT_OK(logEntry.validate()); + + ASSERT_EQUALS(logEntry.getChangeId(), "host.local-2012-11-21T19:14:10-8"); + ASSERT_EQUALS(logEntry.getServer(), "host.local"); + ASSERT_EQUALS(logEntry.getShard(), "shardname"); + ASSERT_EQUALS(logEntry.getClientAddr(), "192.168.0.189:51128"); + ASSERT_EQUALS(logEntry.getTime(), Date_t::fromMillisSinceEpoch(1)); + ASSERT_EQUALS(logEntry.getWhat(), "split"); + ASSERT_BSONOBJ_EQ(logEntry.getDetails(), + BSON("dummy" + << "info")); +} + TEST(ChangeLogType, MissingDetails) { BSONObj obj = BSON(ChangeLogType::changeId("host.local-2012-11-21T19:14:10-8") << ChangeLogType::server("host.local") + << ChangeLogType::shard("shardname") << ChangeLogType::clientAddr("192.168.0.189:51128") << ChangeLogType::time(Date_t::fromMillisSinceEpoch(1)) << ChangeLogType::what("split") @@ -148,6 +182,32 @@ TEST(ChangeLogType, MissingDetails) { ASSERT_EQ(ErrorCodes::NoSuchKey, changeLogResult.getStatus()); } +TEST(ChangeLogType, MissingShard) { + BSONObj obj = BSON(ChangeLogType::changeId("host.local-2012-11-21T19:14:10-8") + << ChangeLogType::server("host.local") + << ChangeLogType::clientAddr("192.168.0.189:51128") + << ChangeLogType::time(Date_t::fromMillisSinceEpoch(1)) + << ChangeLogType::what("split") + << ChangeLogType::ns("test.test") + << ChangeLogType::details(BSON("dummy" + << "info"))); + + auto changeLogResult = ChangeLogType::fromBSON(obj); + ASSERT_OK(changeLogResult.getStatus()); + ChangeLogType& logEntry = changeLogResult.getValue(); + ASSERT_OK(logEntry.validate()); + + ASSERT_EQUALS(logEntry.getChangeId(), "host.local-2012-11-21T19:14:10-8"); + ASSERT_EQUALS(logEntry.getServer(), "host.local"); + ASSERT_EQUALS(logEntry.getClientAddr(), "192.168.0.189:51128"); + ASSERT_EQUALS(logEntry.getTime(), Date_t::fromMillisSinceEpoch(1)); + ASSERT_EQUALS(logEntry.getWhat(), "split"); + ASSERT_EQUALS(logEntry.getNS(), "test.test"); + ASSERT_BSONOBJ_EQ(logEntry.getDetails(), + BSON("dummy" + << "info")); +} + TEST(ChangeLogType, BadType) { ChangeLogType logEntry; BSONObj obj = BSON(ChangeLogType::changeId() << 0); |