diff options
author | Lingzhi Deng <lingzhi.deng@mongodb.com> | 2019-10-05 13:16:42 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-10-05 13:16:42 +0000 |
commit | 150dfeceb607bb40bbae2e5a49ad9bca08f13e25 (patch) | |
tree | 15631469cf3b59fb6398a5df53748c6b74226cfb | |
parent | 2664c92b226bf94bb9da85c58b8820771c79c434 (diff) | |
download | mongo-150dfeceb607bb40bbae2e5a49ad9bca08f13e25.tar.gz |
SERVER-43769: Only get the default write concern from ReplSetConfig if no write concern is specified
-rw-r--r-- | src/mongo/db/repl/repl_set_config.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/write_concern.cpp | 14 | ||||
-rw-r--r-- | src/mongo/db/write_concern_options.cpp | 30 | ||||
-rw-r--r-- | src/mongo/db/write_concern_options.h | 27 | ||||
-rw-r--r-- | src/mongo/s/catalog/sharding_catalog_client_impl.cpp | 1 |
5 files changed, 29 insertions, 46 deletions
diff --git a/src/mongo/db/repl/repl_set_config.cpp b/src/mongo/db/repl/repl_set_config.cpp index 434af8db845..6fa81e2aeb4 100644 --- a/src/mongo/db/repl/repl_set_config.cpp +++ b/src/mongo/db/repl/repl_set_config.cpp @@ -325,8 +325,7 @@ Status ReplSetConfig::_parseSettingsSubdocument(const BSONObj& settings) { return status; } else if (status == ErrorCodes::NoSuchKey) { // Default write concern is w: 1. - _defaultWriteConcern.reset(); - _defaultWriteConcern.wNumNodes = 1; + _defaultWriteConcern = WriteConcernOptions(); } else { return status; } diff --git a/src/mongo/db/write_concern.cpp b/src/mongo/db/write_concern.cpp index 8f05f50e370..30c01e5a831 100644 --- a/src/mongo/db/write_concern.cpp +++ b/src/mongo/db/write_concern.cpp @@ -72,14 +72,24 @@ StatusWith<WriteConcernOptions> extractWriteConcern(OperationContext* opCtx, const BSONObj& cmdObj) { // The default write concern if empty is {w:1}. Specifying {w:0} is/was allowed, but is // interpreted identically to {w:1}. - auto wcResult = WriteConcernOptions::extractWCFromCommand( - cmdObj, repl::ReplicationCoordinator::get(opCtx)->getGetLastErrorDefault()); + auto wcResult = WriteConcernOptions::extractWCFromCommand(cmdObj); if (!wcResult.isOK()) { return wcResult.getStatus(); } WriteConcernOptions writeConcern = wcResult.getValue(); + // Get the default write concern specified in ReplSetConfig only if no write concern is + // specified in the command (when usedDefault is true) to avoid locking the + // ReplicationCoordinator mutex unconditionally. + if (writeConcern.usedDefault) { + writeConcern = repl::ReplicationCoordinator::get(opCtx)->getGetLastErrorDefault(); + if (writeConcern.wNumNodes == 0 && writeConcern.wMode.empty()) { + writeConcern.wNumNodes = 1; + } + writeConcern.usedDefaultW = true; + } + if (writeConcern.usedDefault && serverGlobalParams.clusterRole == ClusterRole::ConfigServer && !opCtx->getClient()->isInDirectClient() && (opCtx->getClient()->session() && diff --git a/src/mongo/db/write_concern_options.cpp b/src/mongo/db/write_concern_options.cpp index 1ad40acebfd..22bb5b49790 100644 --- a/src/mongo/db/write_concern_options.cpp +++ b/src/mongo/db/write_concern_options.cpp @@ -92,7 +92,7 @@ WriteConcernOptions::WriteConcernOptions(const std::string& mode, : syncMode(sync), wNumNodes(0), wMode(mode), wTimeout(durationCount<Milliseconds>(timeout)) {} Status WriteConcernOptions::parse(const BSONObj& obj) { - reset(); + *this = WriteConcernOptions(); if (obj.isEmpty()) { return Status(ErrorCodes::FailedToParse, "write concern object cannot be empty"); } @@ -148,6 +148,7 @@ Status WriteConcernOptions::parse(const BSONObj& obj) { wNumNodes = wEl.numberInt(); usedDefaultW = false; } else if (wEl.type() == String) { + wNumNodes = 0; wMode = wEl.valuestrsafe(); usedDefaultW = false; } else if (wEl.eoo() || wEl.type() == jstNULL || wEl.type() == Undefined) { @@ -159,37 +160,16 @@ Status WriteConcernOptions::parse(const BSONObj& obj) { return Status::OK(); } -namespace { - -/** - * Construct a WriteConcernOptions based on an optional default WC object, in preparation for - * parsing out of a command object or IDL. - */ -WriteConcernOptions constructWCFromDefault( - const WriteConcernOptions& defaultWC = WriteConcernOptions()) { - WriteConcernOptions writeConcern = defaultWC; - writeConcern.usedDefault = true; - writeConcern.usedDefaultW = true; - if (writeConcern.wNumNodes == 0 && writeConcern.wMode.empty()) { - writeConcern.wNumNodes = 1; - } - return writeConcern; -} - -} // namespace - - WriteConcernOptions WriteConcernOptions::deserializerForIDL(const BSONObj& obj) { - WriteConcernOptions writeConcern = constructWCFromDefault(); + WriteConcernOptions writeConcern; if (!obj.isEmpty()) { uassertStatusOK(writeConcern.parse(obj)); } return writeConcern; } -StatusWith<WriteConcernOptions> WriteConcernOptions::extractWCFromCommand( - const BSONObj& cmdObj, const WriteConcernOptions& defaultWC) { - WriteConcernOptions writeConcern = constructWCFromDefault(defaultWC); +StatusWith<WriteConcernOptions> WriteConcernOptions::extractWCFromCommand(const BSONObj& cmdObj) { + WriteConcernOptions writeConcern; // Return the default write concern if no write concern is provided. We check for the existence // of the write concern field up front in order to avoid the expense of constructing an error diff --git a/src/mongo/db/write_concern_options.h b/src/mongo/db/write_concern_options.h index 39025832ea0..c20ba6287fa 100644 --- a/src/mongo/db/write_concern_options.h +++ b/src/mongo/db/write_concern_options.h @@ -57,13 +57,16 @@ public: static constexpr Seconds kWriteConcernTimeoutSharding{60}; static constexpr Seconds kWriteConcernTimeoutUserCommand{60}; - WriteConcernOptions() { - reset(); - // It is assumed that a default-constructed WriteConcernOptions will be populated with the - // default options. If it is subsequently populated with non-default options, it is the - // caller's responsibility to set this flag accordingly. - usedDefault = true; - } + // It is assumed that a default-constructed WriteConcernOptions will be populated with the + // default options. If it is subsequently populated with non-default options, it is the caller's + // responsibility to set the usedDefault and usedDefaultW flag correctly. + WriteConcernOptions() + : syncMode(SyncMode::UNSET), + wNumNodes(1), + wMode(""), + wTimeout(0), + usedDefault(true), + usedDefaultW(true) {} WriteConcernOptions(int numNodes, SyncMode sync, int timeout); @@ -86,8 +89,7 @@ public: * Attempts to extract a writeConcern from cmdObj. * Verifies that the writeConcern is of type Object (BSON type). */ - static StatusWith<WriteConcernOptions> extractWCFromCommand( - const BSONObj& cmdObj, const WriteConcernOptions& defaultWC = WriteConcernOptions()); + static StatusWith<WriteConcernOptions> extractWCFromCommand(const BSONObj& cmdObj); /** * Return true if the server needs to wait for other secondary nodes to satisfy this @@ -95,13 +97,6 @@ public: */ bool needToWaitForOtherNodes() const; - void reset() { - syncMode = SyncMode::UNSET; - wNumNodes = 0; - wMode = ""; - wTimeout = 0; - } - // Returns the BSON representation of this object. // Warning: does not return the same object passed on the last parse() call. BSONObj toBSON() const; diff --git a/src/mongo/s/catalog/sharding_catalog_client_impl.cpp b/src/mongo/s/catalog/sharding_catalog_client_impl.cpp index 4776fed9ed3..4ced819df8a 100644 --- a/src/mongo/s/catalog/sharding_catalog_client_impl.cpp +++ b/src/mongo/s/catalog/sharding_catalog_client_impl.cpp @@ -590,7 +590,6 @@ bool ShardingCatalogClientImpl::runUserManagementWriteCommand(OperationContext* // Make sure that if the command has a write concern that it is w:1 or w:majority, and // convert w:1 or no write concern to w:majority before sending. WriteConcernOptions writeConcern; - writeConcern.reset(); BSONElement writeConcernElement = cmdObj[WriteConcernOptions::kWriteConcernField]; bool initialCmdHadWriteConcern = !writeConcernElement.eoo(); |