summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2015-08-14 15:31:31 -0400
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2015-08-14 15:31:31 -0400
commit1cee34ee3907b7652abdfc7f75ca27ef421a46c4 (patch)
tree54b3e59b4a066e3b3acf4b1bc44998cebf7f6fe5
parentcec89b290906adb7d36507d20d619aaa5a6f6c16 (diff)
downloadmongo-1cee34ee3907b7652abdfc7f75ca27ef421a46c4.tar.gz
Revert "SERVER-19855 Include min OpTime with shard version"
This reverts commit cec89b290906adb7d36507d20d619aaa5a6f6c16.
-rw-r--r--src/mongo/db/repl/optime_pair.h48
-rw-r--r--src/mongo/db/s/set_shard_version_command.cpp10
-rw-r--r--src/mongo/s/SConscript2
-rw-r--r--src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp2
-rw-r--r--src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp9
-rw-r--r--src/mongo/s/chunk_manager.cpp4
-rw-r--r--src/mongo/s/chunk_manager.h9
-rw-r--r--src/mongo/s/chunk_manager_targeter.cpp22
-rw-r--r--src/mongo/s/chunk_version.cpp152
-rw-r--r--src/mongo/s/chunk_version.h178
-rw-r--r--src/mongo/s/mock_ns_targeter.h7
-rw-r--r--src/mongo/s/ns_targeter.h19
-rw-r--r--src/mongo/s/set_shard_version_request.cpp22
-rw-r--r--src/mongo/s/set_shard_version_request.h20
-rw-r--r--src/mongo/s/set_shard_version_request_test.cpp24
-rw-r--r--src/mongo/s/version_manager.cpp90
-rw-r--r--src/mongo/s/write_ops/batch_write_op.cpp9
-rw-r--r--src/mongo/s/write_ops/batched_delete_request_test.cpp32
-rw-r--r--src/mongo/s/write_ops/batched_insert_request_test.cpp32
-rw-r--r--src/mongo/s/write_ops/batched_request_metadata.cpp45
-rw-r--r--src/mongo/s/write_ops/batched_request_metadata.h28
-rw-r--r--src/mongo/s/write_ops/batched_request_metadata_test.cpp16
-rw-r--r--src/mongo/s/write_ops/batched_update_request_test.cpp32
-rw-r--r--src/mongo/s/write_ops/write_op.cpp3
-rw-r--r--src/mongo/s/write_ops/write_op_test.cpp6
25 files changed, 301 insertions, 520 deletions
diff --git a/src/mongo/db/repl/optime_pair.h b/src/mongo/db/repl/optime_pair.h
deleted file mode 100644
index 0f301784f7e..00000000000
--- a/src/mongo/db/repl/optime_pair.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Copyright (C) 2015 MongoDB Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * 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
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * 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 GNU Affero General 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/repl/optime.h"
-
-namespace mongo {
-namespace repl {
-
-template <typename T>
-struct OpTimePair {
-public:
- OpTimePair() = default;
- explicit OpTimePair(T val) : value(std::move(val)) {}
- OpTimePair(T val, OpTime ts) : value(std::move(val)), opTime(std::move(ts)) {}
-
- T value;
- OpTime opTime;
-};
-
-} // namespace repl
-} // namespace mongo
diff --git a/src/mongo/db/s/set_shard_version_command.cpp b/src/mongo/db/s/set_shard_version_command.cpp
index 03b96373844..f95bc3cef7a 100644
--- a/src/mongo/db/s/set_shard_version_command.cpp
+++ b/src/mongo/db/s/set_shard_version_command.cpp
@@ -149,11 +149,15 @@ public:
}
// step 2
- ChunkVersionAndOpTime verAndOpTime =
- uassertStatusOK(ChunkVersionAndOpTime::parseFromBSONForSetShardVersion(cmdObj));
- const auto& version = verAndOpTime.getVersion();
+ if (!ChunkVersion::canParseBSON(cmdObj, "version")) {
+ errmsg = "need to specify version";
+ return false;
+ }
+
+ const ChunkVersion version = ChunkVersion::fromBSON(cmdObj, "version");
// step 3
+
const ChunkVersion oldVersion = info->getVersion(ns);
const ChunkVersion globalVersion = ShardingState::get(txn)->getVersion(ns);
diff --git a/src/mongo/s/SConscript b/src/mongo/s/SConscript
index 72ddfe1549f..df9b3cdef5d 100644
--- a/src/mongo/s/SConscript
+++ b/src/mongo/s/SConscript
@@ -33,13 +33,11 @@ env.Library(
target='common',
source=[
'chunk_diff.cpp',
- 'chunk_version.cpp',
'set_shard_version_request.cpp',
],
LIBDEPS=[
'catalog/catalog_types',
'$BUILD_DIR/mongo/client/connection_string',
- '$BUILD_DIR/mongo/db/repl/optime',
]
)
diff --git a/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp b/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp
index 957f799ba44..73d38b1e610 100644
--- a/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp
+++ b/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp
@@ -607,7 +607,7 @@ Status CatalogManagerLegacy::dropCollection(OperationContext* txn, const Namespa
shardEntry.getName(),
fassertStatusOK(28753, ConnectionString::parse(shardEntry.getHost())),
ns,
- ChunkVersionAndOpTime(ChunkVersion::DROPPED()),
+ ChunkVersion::DROPPED(),
true);
auto ssvResult = shardRegistry->runCommandWithNotMasterRetries(
diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp
index bc8ee282ef3..dcc3e2d68e3 100644
--- a/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp
+++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp
@@ -212,7 +212,7 @@ Status CatalogManagerReplicaSet::shardCollection(OperationContext* txn,
dbPrimaryShardId,
primaryShard->getConnString(),
NamespaceString(ns),
- ChunkVersionAndOpTime(manager->getVersion(), manager->getConfigOpTime()),
+ manager->getVersion(),
true);
auto ssvStatus = grid.shardRegistry()->runCommandWithNotMasterRetries(
@@ -518,18 +518,13 @@ Status CatalogManagerReplicaSet::dropCollection(OperationContext* txn, const Nam
LOG(1) << "dropCollection " << ns << " collection marked as dropped";
- // We just called updateCollection above and this would have advanced the config op time, so use
- // the latest value. On the MongoD side, we need to load the latest config metadata, which
- // indicates that the collection was dropped.
- const ChunkVersionAndOpTime droppedVersion(ChunkVersion::DROPPED(), _getConfigOpTime());
-
for (const auto& shardEntry : allShards) {
SetShardVersionRequest ssv = SetShardVersionRequest::makeForVersioningNoPersist(
grid.shardRegistry()->getConfigServerConnectionString(),
shardEntry.getName(),
fassertStatusOK(28781, ConnectionString::parse(shardEntry.getHost())),
ns,
- droppedVersion,
+ ChunkVersion::DROPPED(),
true);
auto ssvResult = shardRegistry->runCommandWithNotMasterRetries(
diff --git a/src/mongo/s/chunk_manager.cpp b/src/mongo/s/chunk_manager.cpp
index 74fabae55a9..638935ddbf5 100644
--- a/src/mongo/s/chunk_manager.cpp
+++ b/src/mongo/s/chunk_manager.cpp
@@ -172,10 +172,6 @@ ChunkManager::ChunkManager(const CollectionType& coll)
_version = ChunkVersion::fromBSON(coll.toBSON());
}
-repl::OpTime ChunkManager::getConfigOpTime() const {
- return repl::OpTime(Timestamp(0, 0), 0);
-}
-
void ChunkManager::loadExistingRanges(OperationContext* txn, const ChunkManager* oldManager) {
int tries = 3;
diff --git a/src/mongo/s/chunk_manager.h b/src/mongo/s/chunk_manager.h
index 23440fced18..0ca94237920 100644
--- a/src/mongo/s/chunk_manager.h
+++ b/src/mongo/s/chunk_manager.h
@@ -44,10 +44,6 @@ class CollectionType;
struct QuerySolutionNode;
class OperationContext;
-namespace repl {
-class OpTime;
-}
-
typedef std::shared_ptr<ChunkManager> ChunkManagerPtr;
// The key for the map is max for each Chunk or ChunkRange
@@ -158,11 +154,6 @@ public:
return _sequenceNumber;
}
- /**
- * Returns the latest op time from when this chunk manager's data was loaded.
- */
- repl::OpTime getConfigOpTime() const;
-
//
// After constructor is invoked, we need to call loadExistingRanges. If this is a new
// sharded collection, we can call createFirstChunks first.
diff --git a/src/mongo/s/chunk_manager_targeter.cpp b/src/mongo/s/chunk_manager_targeter.cpp
index a3de1e2235e..f4448dafe5d 100644
--- a/src/mongo/s/chunk_manager_targeter.cpp
+++ b/src/mongo/s/chunk_manager_targeter.cpp
@@ -320,8 +320,7 @@ Status ChunkManagerTargeter::targetInsert(OperationContext* txn,
<< "; no metadata found");
}
- *endpoint =
- new ShardEndpoint(_primary->getId(), ChunkVersionAndOpTime(ChunkVersion::UNSHARDED()));
+ *endpoint = new ShardEndpoint(_primary->getId(), ChunkVersion::UNSHARDED());
return Status::OK();
}
}
@@ -497,10 +496,7 @@ Status ChunkManagerTargeter::targetQuery(const BSONObj& query,
for (const ShardId& shardId : shardIds) {
endpoints->push_back(new ShardEndpoint(
- shardId,
- _manager
- ? ChunkVersionAndOpTime(_manager->getVersion(shardId), _manager->getConfigOpTime())
- : ChunkVersionAndOpTime(ChunkVersion::UNSHARDED())));
+ shardId, _manager ? _manager->getVersion(shardId) : ChunkVersion::UNSHARDED()));
}
return Status::OK();
@@ -520,9 +516,7 @@ Status ChunkManagerTargeter::targetShardKey(OperationContext* txn,
_stats.chunkSizeDelta[chunk->getMin()] += estDataSize;
}
- *endpoint = new ShardEndpoint(chunk->getShardId(),
- ChunkVersionAndOpTime(_manager->getVersion(chunk->getShardId()),
- _manager->getConfigOpTime()));
+ *endpoint = new ShardEndpoint(chunk->getShardId(), _manager->getVersion(chunk->getShardId()));
return Status::OK();
}
@@ -543,10 +537,7 @@ Status ChunkManagerTargeter::targetCollection(vector<ShardEndpoint*>* endpoints)
for (const ShardId& shardId : shardIds) {
endpoints->push_back(new ShardEndpoint(
- shardId,
- _manager
- ? ChunkVersionAndOpTime(_manager->getVersion(shardId), _manager->getConfigOpTime())
- : ChunkVersionAndOpTime(ChunkVersion::UNSHARDED())));
+ shardId, _manager ? _manager->getVersion(shardId) : ChunkVersion::UNSHARDED()));
}
return Status::OK();
@@ -564,10 +555,7 @@ Status ChunkManagerTargeter::targetAllShards(vector<ShardEndpoint*>* endpoints)
for (const ShardId& shardId : shardIds) {
endpoints->push_back(new ShardEndpoint(
- shardId,
- _manager
- ? ChunkVersionAndOpTime(_manager->getVersion(shardId), _manager->getConfigOpTime())
- : ChunkVersionAndOpTime(ChunkVersion::UNSHARDED())));
+ shardId, _manager ? _manager->getVersion(shardId) : ChunkVersion::UNSHARDED()));
}
return Status::OK();
diff --git a/src/mongo/s/chunk_version.cpp b/src/mongo/s/chunk_version.cpp
deleted file mode 100644
index 305875d4a6e..00000000000
--- a/src/mongo/s/chunk_version.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/**
- * Copyright (C) 2015 MongoDB Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * 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
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * 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 GNU Affero General 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/s/chunk_version.h"
-
-#include "mongo/bson/bsonobj.h"
-#include "mongo/bson/bsonobjbuilder.h"
-#include "mongo/base/status_with.h"
-#include "mongo/bson/util/bson_extract.h"
-#include "mongo/util/mongoutils/str.h"
-
-namespace mongo {
-namespace {
-
-const char kVersion[] = "version";
-const char kShardVersion[] = "shardVersion";
-
-} // namespace
-
-StatusWith<ChunkVersion> ChunkVersion::parseFromBSONForCommands(const BSONObj& obj) {
- BSONElement versionElem;
- Status status = bsonExtractField(obj, kShardVersion, &versionElem);
- if (!status.isOK())
- return status;
-
- if (versionElem.type() != Array) {
- return {ErrorCodes::TypeMismatch,
- str::stream() << "Invalid type " << versionElem.type()
- << " for shardVersion element. Expected an array"};
- }
-
- BSONObjIterator it(versionElem.Obj());
- if (!it.more())
- return {ErrorCodes::BadValue, "Unexpected empty version"};
-
- ChunkVersion version;
-
- // Expect the timestamp
- {
- BSONElement tsPart = it.next();
- if (tsPart.type() != bsonTimestamp)
- return {ErrorCodes::TypeMismatch,
- str::stream() << "Invalid type " << tsPart.type()
- << " for version timestamp part."};
-
- version._combined = tsPart.timestamp().asULL();
- }
-
- // Expect the epoch OID
- {
- BSONElement epochPart = it.next();
- if (epochPart.type() != jstOID)
- return {ErrorCodes::TypeMismatch,
- str::stream() << "Invalid type " << epochPart.type()
- << " for version epoch part."};
-
- version._epoch = epochPart.OID();
- }
-
- return version;
-}
-
-StatusWith<ChunkVersion> ChunkVersion::parseFromBSONForSetShardVersion(const BSONObj& obj) {
- bool canParse;
- const ChunkVersion chunkVersion = ChunkVersion::fromBSON(obj, kVersion, &canParse);
- if (!canParse)
- return {ErrorCodes::BadValue, "Unable to parse shard version"};
-
- return chunkVersion;
-}
-
-
-ChunkVersionAndOpTime::ChunkVersionAndOpTime(ChunkVersion chunkVersion)
- : _verAndOpT(chunkVersion) {}
-
-ChunkVersionAndOpTime::ChunkVersionAndOpTime(ChunkVersion chunkVersion, repl::OpTime ts)
- : _verAndOpT(chunkVersion, ts) {}
-
-StatusWith<ChunkVersionAndOpTime> ChunkVersionAndOpTime::parseFromBSONForCommands(
- const BSONObj& obj) {
- const auto chunkVersionStatus = ChunkVersion::parseFromBSONForCommands(obj);
- if (!chunkVersionStatus.isOK())
- return chunkVersionStatus.getStatus();
-
- const ChunkVersion& chunkVersion = chunkVersionStatus.getValue();
-
- const auto opTimeStatus = repl::OpTime::parseFromBSON(obj);
- if (opTimeStatus.isOK()) {
- return ChunkVersionAndOpTime(chunkVersion, opTimeStatus.getValue());
- } else if (opTimeStatus == ErrorCodes::NoSuchKey) {
- return ChunkVersionAndOpTime(chunkVersion);
- }
-
- return opTimeStatus.getStatus();
-}
-
-StatusWith<ChunkVersionAndOpTime> ChunkVersionAndOpTime::parseFromBSONForSetShardVersion(
- const BSONObj& obj) {
- const auto chunkVersionStatus = ChunkVersion::parseFromBSONForSetShardVersion(obj);
- if (!chunkVersionStatus.isOK())
- return chunkVersionStatus.getStatus();
-
- const ChunkVersion& chunkVersion = chunkVersionStatus.getValue();
-
- const auto opTimeStatus = repl::OpTime::parseFromBSON(obj);
- if (opTimeStatus.isOK()) {
- return ChunkVersionAndOpTime(chunkVersion, opTimeStatus.getValue());
- } else if (opTimeStatus == ErrorCodes::NoSuchKey) {
- return ChunkVersionAndOpTime(chunkVersion);
- }
-
- return opTimeStatus.getStatus();
-}
-
-void ChunkVersionAndOpTime::appendForSetShardVersion(BSONObjBuilder* builder) const {
- _verAndOpT.value.addToBSON(*builder, kVersion);
- _verAndOpT.opTime.append(builder);
-}
-
-void ChunkVersionAndOpTime::appendForCommands(BSONObjBuilder* builder) const {
- builder->appendArray(kShardVersion, _verAndOpT.value.toBSON());
- _verAndOpT.opTime.append(builder);
-}
-
-} // namespace mongo
diff --git a/src/mongo/s/chunk_version.h b/src/mongo/s/chunk_version.h
index 7c4b2655412..02a05f3dd57 100644
--- a/src/mongo/s/chunk_version.h
+++ b/src/mongo/s/chunk_version.h
@@ -1,42 +1,37 @@
/**
- * Copyright (C) 2012-2015 MongoDB Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * 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
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * 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 GNU Affero General 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.
- */
+* Copyright (C) 2012 10gen Inc.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License, version 3,
+* as published by the Free Software Foundation.
+*
+* 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
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* 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 GNU Affero General 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/jsobj.h"
-#include "mongo/db/repl/optime_pair.h"
namespace mongo {
-class BSONObj;
-template <typename T>
-class StatusWith;
-
/**
* ChunkVersions consist of a major/minor version scoped to a version epoch
*
@@ -51,38 +46,32 @@ class StatusWith;
* expected from types.
*/
struct ChunkVersion {
-public:
+ union {
+ struct {
+ int _minor;
+ int _major;
+ };
+ unsigned long long _combined;
+ };
+ OID _epoch;
+
ChunkVersion() : _minor(0), _major(0), _epoch(OID()) {}
+ //
+ // Constructors shouldn't have default parameters here, since it's vital we track from
+ // here on the epochs of versions, even if not used.
+ //
+
ChunkVersion(int major, int minor, const OID& epoch)
: _minor(minor), _major(major), _epoch(epoch) {}
- /**
- * Interprets the specified BSON content as the format for commands, which is in the form:
- * { ..., shardVersion: [ <combined major/minor>, <OID epoch> ], ... }
- */
- static StatusWith<ChunkVersion> parseFromBSONForCommands(const BSONObj& obj);
-
- /**
- * Interprets the specified BSON content as the format for the setShardVersion command, which
- * is in the form:
- * { ..., version: [ <combined major/minor> ], versionEpoch: [ <OID epoch> ], ... }
- */
- static StatusWith<ChunkVersion> parseFromBSONForSetShardVersion(const BSONObj& obj);
-
- /**
- * Indicates a dropped collection. All components are zeroes (OID is zero time, zero
- * machineId/inc).
- */
static ChunkVersion DROPPED() {
- return ChunkVersion(0, 0, OID());
+ return ChunkVersion(0, 0, OID()); // dropped OID is zero time, zero machineId/inc
}
- /**
- * Indicates that the collection is not sharded. Same as DROPPED.
- */
static ChunkVersion UNSHARDED() {
- return ChunkVersion(0, 0, OID());
+ // TODO: Distinguish between these cases
+ return DROPPED();
}
static ChunkVersion IGNORED() {
@@ -380,23 +369,35 @@ public:
return b.arr();
}
+ bool parseBSON(const BSONObj& source, std::string* errMsg) {
+ // ChunkVersion wants to be an array.
+ BSONArray arrSource = static_cast<BSONArray>(source);
+
+ bool canParse;
+ ChunkVersion version = fromBSON(arrSource, &canParse);
+ if (!canParse) {
+ *errMsg = "Could not parse version structure";
+ return false;
+ }
+
+ _minor = version._minor;
+ _major = version._major;
+ _epoch = version._epoch;
+ return true;
+ }
+
void clear() {
_minor = 0;
_major = 0;
_epoch = OID();
}
-private:
- union {
- struct {
- int _minor;
- int _major;
- };
-
- uint64_t _combined;
- };
-
- OID _epoch;
+ void cloneTo(ChunkVersion* other) const {
+ other->clear();
+ other->_minor = _minor;
+ other->_major = _major;
+ other->_epoch = _epoch;
+ }
};
inline std::ostream& operator<<(std::ostream& s, const ChunkVersion& v) {
@@ -404,51 +405,4 @@ inline std::ostream& operator<<(std::ostream& s, const ChunkVersion& v) {
return s;
}
-
-/**
- * Represents a chunk version along with the optime from when it was retrieved. Provides logic to
- * serialize and deserialize the combo to BSON.
- */
-class ChunkVersionAndOpTime {
-public:
- ChunkVersionAndOpTime(ChunkVersion chunkVersion);
- ChunkVersionAndOpTime(ChunkVersion chunkVersion, repl::OpTime ts);
-
- const ChunkVersion& getVersion() const {
- return _verAndOpT.value;
- }
-
- const repl::OpTime& getOpTime() const {
- return _verAndOpT.opTime;
- }
-
- /**
- * Interprets the contents of the BSON documents as having been constructed in the format for
- * write commands. The optime component is optional for backwards compatibility and if not
- * present, the optime will be default initialized.
- */
- static StatusWith<ChunkVersionAndOpTime> parseFromBSONForCommands(const BSONObj& obj);
-
- /**
- * Interprets the contents of the BSON document as having been constructed in the format for the
- * setShardVersion command. The optime component is optional for backwards compatibility and if
- * not present, the optime will be default initialized.
- */
- static StatusWith<ChunkVersionAndOpTime> parseFromBSONForSetShardVersion(const BSONObj& obj);
-
- /**
- * Appends the contents to the specified builder in the format expected by the setShardVersion
- * command.
- */
- void appendForSetShardVersion(BSONObjBuilder* builder) const;
-
- /**
- * Appends the contents to the specified builder in the format expected by the write commands.
- */
- void appendForCommands(BSONObjBuilder* builder) const;
-
-private:
- repl::OpTimePair<ChunkVersion> _verAndOpT;
-};
-
} // namespace mongo
diff --git a/src/mongo/s/mock_ns_targeter.h b/src/mongo/s/mock_ns_targeter.h
index 79c6d517445..44bc5be18c2 100644
--- a/src/mongo/s/mock_ns_targeter.h
+++ b/src/mongo/s/mock_ns_targeter.h
@@ -211,11 +211,8 @@ private:
inline void assertEndpointsEqual(const ShardEndpoint& endpointA, const ShardEndpoint& endpointB) {
ASSERT_EQUALS(endpointA.shardName, endpointB.shardName);
- ASSERT_EQUALS(endpointA.shardVersion.getVersion().toLong(),
- endpointB.shardVersion.getVersion().toLong());
- ASSERT_EQUALS(endpointA.shardVersion.getVersion().epoch(),
- endpointB.shardVersion.getVersion().epoch());
- ASSERT_EQUALS(endpointA.shardVersion.getOpTime(), endpointB.shardVersion.getOpTime());
+ ASSERT_EQUALS(endpointA.shardVersion.toLong(), endpointB.shardVersion.toLong());
+ ASSERT_EQUALS(endpointA.shardVersion.epoch(), endpointB.shardVersion.epoch());
}
} // namespace mongo
diff --git a/src/mongo/s/ns_targeter.h b/src/mongo/s/ns_targeter.h
index 1e6182b67b7..087725697d2 100644
--- a/src/mongo/s/ns_targeter.h
+++ b/src/mongo/s/ns_targeter.h
@@ -157,11 +157,26 @@ struct ShardEndpoint {
ShardEndpoint(const ShardEndpoint& other)
: shardName(other.shardName), shardVersion(other.shardVersion) {}
- ShardEndpoint(const std::string& shardName, const ChunkVersionAndOpTime& shardVersion)
+ ShardEndpoint(const std::string& shardName, const ChunkVersion& shardVersion)
: shardName(shardName), shardVersion(shardVersion) {}
const std::string shardName;
- const ChunkVersionAndOpTime shardVersion;
+ const ChunkVersion shardVersion;
+
+ //
+ // For testing *only* - do not use as part of API
+ //
+
+ BSONObj toBSON() const {
+ BSONObjBuilder b;
+ appendBSON(&b);
+ return b.obj();
+ }
+
+ void appendBSON(BSONObjBuilder* builder) const {
+ builder->append("shardName", shardName);
+ shardVersion.addToBSON(*builder, "shardVersion");
+ }
};
} // namespace mongo
diff --git a/src/mongo/s/set_shard_version_request.cpp b/src/mongo/s/set_shard_version_request.cpp
index 15389a66d43..eb843a963dd 100644
--- a/src/mongo/s/set_shard_version_request.cpp
+++ b/src/mongo/s/set_shard_version_request.cpp
@@ -46,6 +46,7 @@ const char kShardName[] = "shard";
const char kShardConnectionString[] = "shardHost";
const char kInit[] = "init";
const char kAuthoritative[] = "authoritative";
+const char kVersion[] = "version";
const char kNoConnectionVersioning[] = "noConnectionVersioning";
} // namespace
@@ -63,7 +64,7 @@ SetShardVersionRequest::SetShardVersionRequest(ConnectionString configServer,
std::string shardName,
ConnectionString shardConnectionString,
NamespaceString nss,
- ChunkVersionAndOpTime version,
+ ChunkVersion version,
bool isAuthoritative)
: _init(false),
_isAuthoritative(isAuthoritative),
@@ -87,7 +88,7 @@ SetShardVersionRequest SetShardVersionRequest::makeForVersioning(
const std::string& shardName,
const ConnectionString& shardConnectionString,
const NamespaceString& nss,
- const ChunkVersionAndOpTime& nssVersion,
+ const ChunkVersion& nssVersion,
bool isAuthoritative) {
return SetShardVersionRequest(
configServer, shardName, shardConnectionString, nss, nssVersion, isAuthoritative);
@@ -98,7 +99,7 @@ SetShardVersionRequest SetShardVersionRequest::makeForVersioningNoPersist(
const std::string& shardName,
const ConnectionString& shard,
const NamespaceString& nss,
- const ChunkVersionAndOpTime& nssVersion,
+ const ChunkVersion& nssVersion,
bool isAuthoritative) {
auto ssv = makeForVersioning(configServer, shardName, shard, nss, nssVersion, isAuthoritative);
ssv._noConnectionVersioning = true;
@@ -184,11 +185,14 @@ StatusWith<SetShardVersionRequest> SetShardVersionRequest::parseFromBSON(const B
}
{
- auto versionStatus = ChunkVersionAndOpTime::parseFromBSONForSetShardVersion(cmdObj);
- if (!versionStatus.isOK())
- return versionStatus.getStatus();
+ bool canParse;
- request._version = versionStatus.getValue();
+ ChunkVersion chunkVersion = ChunkVersion::fromBSON(cmdObj, kVersion, &canParse);
+ if (!canParse) {
+ return {ErrorCodes::BadValue, "Unable to parse shard version"};
+ }
+
+ request._version = std::move(chunkVersion);
}
return request;
@@ -205,7 +209,7 @@ BSONObj SetShardVersionRequest::toBSON() const {
cmdBuilder.append(kShardConnectionString, _shardCS.toString());
if (!_init) {
- _version.get().appendForSetShardVersion(&cmdBuilder);
+ _version.get().addToBSON(cmdBuilder, kVersion);
}
if (_noConnectionVersioning) {
@@ -222,7 +226,7 @@ const NamespaceString& SetShardVersionRequest::getNS() const {
const ChunkVersion SetShardVersionRequest::getNSVersion() const {
invariant(!_init);
- return _version.get().getVersion();
+ return _version.get();
}
} // namespace mongo
diff --git a/src/mongo/s/set_shard_version_request.h b/src/mongo/s/set_shard_version_request.h
index 3f06b4546c8..02fcb3099dc 100644
--- a/src/mongo/s/set_shard_version_request.h
+++ b/src/mongo/s/set_shard_version_request.h
@@ -38,6 +38,7 @@
namespace mongo {
class BSONObj;
+struct ChunkVersion;
template <typename T>
class StatusWith;
@@ -66,7 +67,7 @@ public:
const std::string& shardName,
const ConnectionString& shard,
const NamespaceString& nss,
- const ChunkVersionAndOpTime& nssVersion,
+ const ChunkVersion& nssVersion,
bool isAuthoritative);
/**
@@ -76,13 +77,12 @@ public:
* connection WILL NOT be marked as "versioned". DO NOT USE unless the command will be sent
* through the TaskExecutor.
*/
- static SetShardVersionRequest makeForVersioningNoPersist(
- const ConnectionString& configServer,
- const std::string& shardName,
- const ConnectionString& shard,
- const NamespaceString& nss,
- const ChunkVersionAndOpTime& nssVersion,
- bool isAuthoritative);
+ static SetShardVersionRequest makeForVersioningNoPersist(const ConnectionString& configServer,
+ const std::string& shardName,
+ const ConnectionString& shard,
+ const NamespaceString& nss,
+ const ChunkVersion& nssVersion,
+ bool isAuthoritative);
/**
* Parses an SSV request from a set shard version command.
@@ -153,7 +153,7 @@ private:
std::string shardName,
ConnectionString shardConnectionString,
NamespaceString nss,
- ChunkVersionAndOpTime version,
+ ChunkVersion nssVersion,
bool isAuthoritative);
SetShardVersionRequest();
@@ -169,7 +169,7 @@ private:
// These values are only set if _init is false
boost::optional<NamespaceString> _nss;
- boost::optional<ChunkVersionAndOpTime> _version;
+ boost::optional<ChunkVersion> _version;
};
} // namespace mongo
diff --git a/src/mongo/s/set_shard_version_request_test.cpp b/src/mongo/s/set_shard_version_request_test.cpp
index ab370835f7a..6328a9763c2 100644
--- a/src/mongo/s/set_shard_version_request_test.cpp
+++ b/src/mongo/s/set_shard_version_request_test.cpp
@@ -215,8 +215,7 @@ TEST(SetShardVersionRequest, ToSSVCommandInit) {
}
TEST(SetShardVersionRequest, ToSSVCommandFull) {
- const ChunkVersionAndOpTime chunkVersion(ChunkVersion(1, 2, OID::gen()),
- repl::OpTime(Timestamp(10), 20LL));
+ const ChunkVersion chunkVersion(1, 2, OID::gen());
SetShardVersionRequest ssv = SetShardVersionRequest::makeForVersioning(
configCS, "TestShard", shardCS, NamespaceString("db.coll"), chunkVersion, false);
@@ -229,7 +228,7 @@ TEST(SetShardVersionRequest, ToSSVCommandFull) {
ASSERT_EQ(ssv.getShardConnectionString().toString(), shardCS.toString());
ASSERT_EQ(ssv.getNS().ns(), "db.coll");
ASSERT_EQ(ssv.getNSVersion().toBSONWithPrefix("version"),
- chunkVersion.getVersion().toBSONWithPrefix("version"));
+ chunkVersion.toBSONWithPrefix("version"));
ASSERT_EQ(ssv.toBSON(),
BSON("setShardVersion"
@@ -238,13 +237,11 @@ TEST(SetShardVersionRequest, ToSSVCommandFull) {
<< configCS.toString() << "shard"
<< "TestShard"
<< "shardHost" << shardCS.toString() << "version"
- << Timestamp(chunkVersion.getVersion().toLong()) << "versionEpoch"
- << chunkVersion.getVersion().epoch() << "ts" << Timestamp(10) << "t" << 20LL));
+ << Timestamp(chunkVersion.toLong()) << "versionEpoch" << chunkVersion.epoch()));
}
TEST(SetShardVersionRequest, ToSSVCommandFullAuthoritative) {
- const ChunkVersionAndOpTime chunkVersion(ChunkVersion(1, 2, OID::gen()),
- repl::OpTime(Timestamp(10), 20LL));
+ const ChunkVersion chunkVersion(1, 2, OID::gen());
SetShardVersionRequest ssv = SetShardVersionRequest::makeForVersioning(
configCS, "TestShard", shardCS, NamespaceString("db.coll"), chunkVersion, true);
@@ -257,7 +254,7 @@ TEST(SetShardVersionRequest, ToSSVCommandFullAuthoritative) {
ASSERT_EQ(ssv.getShardConnectionString().toString(), shardCS.toString());
ASSERT_EQ(ssv.getNS().ns(), "db.coll");
ASSERT_EQ(ssv.getNSVersion().toBSONWithPrefix("version"),
- chunkVersion.getVersion().toBSONWithPrefix("version"));
+ chunkVersion.toBSONWithPrefix("version"));
ASSERT_EQ(ssv.toBSON(),
BSON("setShardVersion"
@@ -266,13 +263,11 @@ TEST(SetShardVersionRequest, ToSSVCommandFullAuthoritative) {
<< configCS.toString() << "shard"
<< "TestShard"
<< "shardHost" << shardCS.toString() << "version"
- << Timestamp(chunkVersion.getVersion().toLong()) << "versionEpoch"
- << chunkVersion.getVersion().epoch() << "ts" << Timestamp(10) << "t" << 20LL));
+ << Timestamp(chunkVersion.toLong()) << "versionEpoch" << chunkVersion.epoch()));
}
TEST(SetShardVersionRequest, ToSSVCommandFullNoConnectionVersioning) {
- const ChunkVersionAndOpTime chunkVersion(ChunkVersion(1, 2, OID::gen()),
- repl::OpTime(Timestamp(10), 20LL));
+ const ChunkVersion chunkVersion(1, 2, OID::gen());
SetShardVersionRequest ssv = SetShardVersionRequest::makeForVersioningNoPersist(
configCS, "TestShard", shardCS, NamespaceString("db.coll"), chunkVersion, true);
@@ -285,7 +280,7 @@ TEST(SetShardVersionRequest, ToSSVCommandFullNoConnectionVersioning) {
ASSERT_EQ(ssv.getShardConnectionString().toString(), shardCS.toString());
ASSERT_EQ(ssv.getNS().ns(), "db.coll");
ASSERT_EQ(ssv.getNSVersion().toBSONWithPrefix("version"),
- chunkVersion.getVersion().toBSONWithPrefix("version"));
+ chunkVersion.toBSONWithPrefix("version"));
ASSERT_EQ(ssv.toBSON(),
BSON("setShardVersion"
@@ -294,8 +289,7 @@ TEST(SetShardVersionRequest, ToSSVCommandFullNoConnectionVersioning) {
<< configCS.toString() << "shard"
<< "TestShard"
<< "shardHost" << shardCS.toString() << "version"
- << Timestamp(chunkVersion.getVersion().toLong()) << "versionEpoch"
- << chunkVersion.getVersion().epoch() << "ts" << Timestamp(10) << "t" << 20LL
+ << Timestamp(chunkVersion.toLong()) << "versionEpoch" << chunkVersion.epoch()
<< "noConnectionVersioning" << true));
}
diff --git a/src/mongo/s/version_manager.cpp b/src/mongo/s/version_manager.cpp
index 4d4f87a3159..a77243627d5 100644
--- a/src/mongo/s/version_manager.cpp
+++ b/src/mongo/s/version_manager.cpp
@@ -1,30 +1,32 @@
+// @file version_manager.cpp
+
/**
- * Copyright (C) 2010-2015 MongoDB Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * 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
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * 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 GNU Affero General 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.
- */
+* Copyright (C) 2010 10gen Inc.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License, version 3,
+* as published by the Free Software Foundation.
+*
+* 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
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* 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 GNU Affero General 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
@@ -43,7 +45,6 @@
#include "mongo/s/config.h"
#include "mongo/s/grid.h"
#include "mongo/s/mongos_options.h"
-#include "mongo/s/set_shard_version_request.h"
#include "mongo/s/stale_exception.h"
#include "mongo/util/log.h"
@@ -110,36 +111,35 @@ private:
*/
bool setShardVersion(DBClientBase& conn,
const string& ns,
- const ConnectionString& configServer,
+ const string& configServerPrimary,
ChunkVersion version,
ChunkManager* manager,
bool authoritative,
BSONObj& result) {
+ BSONObjBuilder cmdBuilder;
+ cmdBuilder.append("setShardVersion", ns);
+ cmdBuilder.append("configdb", configServerPrimary);
+
ShardId shardId;
- ConnectionString shardCS;
{
const auto shard = grid.shardRegistry()->getShard(conn.getServerAddress());
shardId = shard->getId();
- shardCS = shard->getConnString();
+ cmdBuilder.append("shard", shardId);
+ cmdBuilder.append("shardHost", shard->getConnString().toString());
}
- BSONObj cmd;
-
- if (ns.empty()) {
- SetShardVersionRequest ssv =
- SetShardVersionRequest::makeForInit(configServer, shardId, shardCS);
- cmd = ssv.toBSON();
+ if (ns.size() > 0) {
+ version.addToBSON(cmdBuilder);
} else {
- const ChunkVersionAndOpTime verAndOpT = manager
- ? ChunkVersionAndOpTime(version, manager->getConfigOpTime())
- : ChunkVersionAndOpTime(version);
-
- SetShardVersionRequest ssv = SetShardVersionRequest::makeForVersioning(
- configServer, shardId, shardCS, NamespaceString(ns), verAndOpT, authoritative);
+ cmdBuilder.append("init", true);
+ }
- cmd = ssv.toBSON();
+ if (authoritative) {
+ cmdBuilder.appendBool("authoritative", 1);
}
+ BSONObj cmd = cmdBuilder.obj();
+
LOG(1) << " setShardVersion " << shardId << " " << conn.getServerAddress() << " " << ns
<< " " << cmd
<< (manager ? string(str::stream() << " " << manager->getSequenceNumber()) : "");
@@ -214,7 +214,7 @@ bool initShardVersionEmptyNS(OperationContext* txn, DBClientBase* conn_in) {
ok = setShardVersion(*conn,
"",
- grid.shardRegistry()->getConfigServerConnectionString(),
+ grid.shardRegistry()->getConfigServerConnectionString().toString(),
ChunkVersion(),
NULL,
true,
@@ -373,7 +373,7 @@ bool checkShardVersion(OperationContext* txn,
BSONObj result;
if (setShardVersion(*conn,
ns,
- grid.shardRegistry()->getConfigServerConnectionString(),
+ grid.shardRegistry()->getConfigServerConnectionString().toString(),
version,
manager.get(),
authoritative,
diff --git a/src/mongo/s/write_ops/batch_write_op.cpp b/src/mongo/s/write_ops/batch_write_op.cpp
index ba7ddae8d95..113dd9133f8 100644
--- a/src/mongo/s/write_ops/batch_write_op.cpp
+++ b/src/mongo/s/write_ops/batch_write_op.cpp
@@ -87,13 +87,11 @@ static int compareEndpoints(const ShardEndpoint* endpointA, const ShardEndpoint*
if (shardNameDiff != 0)
return shardNameDiff;
- long shardVersionDiff = endpointA->shardVersion.getVersion().toLong() -
- endpointB->shardVersion.getVersion().toLong();
+ long shardVersionDiff = endpointA->shardVersion.toLong() - endpointB->shardVersion.toLong();
if (shardVersionDiff != 0)
return shardVersionDiff;
- int shardEpochDiff = endpointA->shardVersion.getVersion().epoch().compare(
- endpointB->shardVersion.getVersion().epoch());
+ int shardEpochDiff = endpointA->shardVersion.epoch().compare(endpointB->shardVersion.epoch());
return shardEpochDiff;
}
@@ -458,8 +456,7 @@ void BatchWriteOp::buildBatchRequest(const TargetedWriteBatch& targetedBatch,
unique_ptr<BatchedRequestMetadata> requestMetadata(new BatchedRequestMetadata());
requestMetadata->setShardName(targetedBatch.getEndpoint().shardName);
- requestMetadata->setShardVersion(
- ChunkVersionAndOpTime(targetedBatch.getEndpoint().shardVersion));
+ requestMetadata->setShardVersion(targetedBatch.getEndpoint().shardVersion);
requestMetadata->setSession(0);
request->setMetadata(requestMetadata.release());
}
diff --git a/src/mongo/s/write_ops/batched_delete_request_test.cpp b/src/mongo/s/write_ops/batched_delete_request_test.cpp
index c8f71652599..87d883f1b0b 100644
--- a/src/mongo/s/write_ops/batched_delete_request_test.cpp
+++ b/src/mongo/s/write_ops/batched_delete_request_test.cpp
@@ -46,24 +46,32 @@ TEST(BatchedDeleteRequest, Basic) {
BSON(BatchedDeleteDocument::query(BSON("a" << 1)) << BatchedDeleteDocument::limit(1))
<< BSON(BatchedDeleteDocument::query(BSON("b" << 1)) << BatchedDeleteDocument::limit(1)));
- BSONObj origDeleteRequestObj = BSON(
- BatchedDeleteRequest::collName("test")
- << BatchedDeleteRequest::deletes() << deleteArray
- << BatchedDeleteRequest::writeConcern(BSON("w" << 1)) << BatchedDeleteRequest::ordered(true)
- << BatchedDeleteRequest::metadata() << BSON("shardName"
- << "shard000"
- << "shardVersion"
- << BSON_ARRAY(Timestamp(1, 2) << OID::gen())
- << "ts" << Timestamp(3, 4) << "t" << 5
- << "session" << 0LL));
+ BSONObj writeConcernObj = BSON("w" << 1);
+
+ // The BSON_ARRAY macro doesn't support Timestamps.
+ BSONArrayBuilder arrBuilder;
+ arrBuilder.append(Timestamp(1, 1));
+ arrBuilder.append(OID::gen());
+ BSONArray shardVersionArray = arrBuilder.arr();
+
+ BSONObj origDeleteRequestObj =
+ BSON(BatchedDeleteRequest::collName("test")
+ << BatchedDeleteRequest::deletes() << deleteArray
+ << BatchedDeleteRequest::writeConcern(writeConcernObj)
+ << BatchedDeleteRequest::ordered(true) << BatchedDeleteRequest::metadata()
+ << BSON(BatchedRequestMetadata::shardName("shard000")
+ << BatchedRequestMetadata::shardVersion() << shardVersionArray
+ << BatchedRequestMetadata::session(0)));
string errMsg;
BatchedDeleteRequest request;
- ASSERT_TRUE(request.parseBSON("foo", origDeleteRequestObj, &errMsg));
+ bool ok = request.parseBSON("foo", origDeleteRequestObj, &errMsg);
+ ASSERT_TRUE(ok);
ASSERT_EQ("foo.test", request.getNS().ns());
- ASSERT_EQUALS(origDeleteRequestObj, request.toBSON());
+ BSONObj genDeleteRequestObj = request.toBSON();
+ ASSERT_EQUALS(0, genDeleteRequestObj.woCompare(origDeleteRequestObj));
}
} // namespace
diff --git a/src/mongo/s/write_ops/batched_insert_request_test.cpp b/src/mongo/s/write_ops/batched_insert_request_test.cpp
index 09e8e950c08..e31503d431f 100644
--- a/src/mongo/s/write_ops/batched_insert_request_test.cpp
+++ b/src/mongo/s/write_ops/batched_insert_request_test.cpp
@@ -45,24 +45,32 @@ namespace {
TEST(BatchedInsertRequest, Basic) {
BSONArray insertArray = BSON_ARRAY(BSON("a" << 1) << BSON("b" << 1));
- BSONObj origInsertRequestObj = BSON(
- BatchedInsertRequest::collName("test")
- << BatchedInsertRequest::documents() << insertArray
- << BatchedInsertRequest::writeConcern(BSON("w" << 1)) << BatchedInsertRequest::ordered(true)
- << BatchedInsertRequest::metadata() << BSON("shardName"
- << "shard000"
- << "shardVersion"
- << BSON_ARRAY(Timestamp(1, 2) << OID::gen())
- << "ts" << Timestamp(3, 4) << "t" << 5
- << "session" << 0LL));
+ BSONObj writeConcernObj = BSON("w" << 1);
+
+ // The BSON_ARRAY macro doesn't support Timestamps.
+ BSONArrayBuilder arrBuilder;
+ arrBuilder.append(Timestamp(1, 1));
+ arrBuilder.append(OID::gen());
+ BSONArray shardVersionArray = arrBuilder.arr();
+
+ BSONObj origInsertRequestObj =
+ BSON(BatchedInsertRequest::collName("test")
+ << BatchedInsertRequest::documents() << insertArray
+ << BatchedInsertRequest::writeConcern(writeConcernObj)
+ << BatchedInsertRequest::ordered(true) << BatchedInsertRequest::metadata()
+ << BSON(BatchedRequestMetadata::shardName("shard0000")
+ << BatchedRequestMetadata::shardVersion() << shardVersionArray
+ << BatchedRequestMetadata::session(0)));
string errMsg;
BatchedInsertRequest request;
- ASSERT_TRUE(request.parseBSON("foo", origInsertRequestObj, &errMsg));
+ bool ok = request.parseBSON("foo", origInsertRequestObj, &errMsg);
+ ASSERT_TRUE(ok);
ASSERT_EQ("foo.test", request.getNS().ns());
- ASSERT_EQUALS(origInsertRequestObj, request.toBSON());
+ BSONObj genInsertRequestObj = request.toBSON();
+ ASSERT_EQUALS(0, genInsertRequestObj.woCompare(origInsertRequestObj));
}
TEST(BatchedInsertRequest, GenIDAll) {
diff --git a/src/mongo/s/write_ops/batched_request_metadata.cpp b/src/mongo/s/write_ops/batched_request_metadata.cpp
index 78ecefbb9df..a2e21f99e4c 100644
--- a/src/mongo/s/write_ops/batched_request_metadata.cpp
+++ b/src/mongo/s/write_ops/batched_request_metadata.cpp
@@ -26,8 +26,6 @@
* it in the license file.
*/
-#include "mongo/platform/basic.h"
-
#include "mongo/s/write_ops/batched_request_metadata.h"
#include "mongo/db/field_parser.h"
@@ -57,8 +55,9 @@ BSONObj BatchedRequestMetadata::toBSON() const {
if (_isShardNameSet)
metadataBuilder << shardName(_shardName);
- if (_shardVersion) {
- _shardVersion.get().appendForCommands(&metadataBuilder);
+ if (_shardVersion.get()) {
+ // ChunkVersion wants to be an array.
+ metadataBuilder.append(shardVersion(), static_cast<BSONArray>(_shardVersion->toBSON()));
}
if (_isSessionSet)
@@ -81,12 +80,12 @@ bool BatchedRequestMetadata::parseBSON(const BSONObj& source, string* errMsg) {
_isShardNameSet = fieldState == FieldParser::FIELD_SET;
{
- auto verAndOpTStatus = ChunkVersionAndOpTime::parseFromBSONForCommands(source);
- if (!verAndOpTStatus.isOK()) {
+ std::unique_ptr<ChunkVersion> tempChunkVersion(new ChunkVersion);
+ fieldState = FieldParser::extract(source, shardVersion, tempChunkVersion.get(), errMsg);
+ if (fieldState == FieldParser::FIELD_INVALID)
return false;
- }
-
- _shardVersion = verAndOpTStatus.getValue();
+ if (fieldState == FieldParser::FIELD_SET)
+ _shardVersion.swap(tempChunkVersion);
}
fieldState = FieldParser::extract(source, session, &_session, errMsg);
@@ -114,7 +113,10 @@ string BatchedRequestMetadata::toString() const {
void BatchedRequestMetadata::cloneTo(BatchedRequestMetadata* other) const {
other->_shardName = _shardName;
other->_isShardNameSet = _isShardNameSet;
- other->_shardVersion = _shardVersion;
+
+ if (other->_shardVersion.get())
+ _shardVersion->cloneTo(other->_shardVersion.get());
+
other->_session = _session;
other->_isSessionSet = _isSessionSet;
}
@@ -124,21 +126,36 @@ void BatchedRequestMetadata::setShardName(StringData shardName) {
_isShardNameSet = true;
}
+void BatchedRequestMetadata::unsetShardName() {
+ _isShardNameSet = false;
+}
+
+bool BatchedRequestMetadata::isShardNameSet() const {
+ return _isShardNameSet;
+}
+
const string& BatchedRequestMetadata::getShardName() const {
dassert(_isShardNameSet);
return _shardName;
}
-void BatchedRequestMetadata::setShardVersion(const ChunkVersionAndOpTime& shardVersion) {
- _shardVersion = shardVersion;
+void BatchedRequestMetadata::setShardVersion(const ChunkVersion& shardVersion) {
+ unique_ptr<ChunkVersion> temp(new ChunkVersion);
+ shardVersion.cloneTo(temp.get());
+ _shardVersion.reset(temp.release());
+}
+
+void BatchedRequestMetadata::unsetShardVersion() {
+ _shardVersion.reset();
}
bool BatchedRequestMetadata::isShardVersionSet() const {
- return _shardVersion.is_initialized();
+ return _shardVersion.get() != NULL;
}
const ChunkVersion& BatchedRequestMetadata::getShardVersion() const {
- return _shardVersion.get().getVersion();
+ dassert(_shardVersion.get());
+ return *_shardVersion;
}
void BatchedRequestMetadata::setSession(long long session) {
diff --git a/src/mongo/s/write_ops/batched_request_metadata.h b/src/mongo/s/write_ops/batched_request_metadata.h
index 2b885e9018d..6e31cb60713 100644
--- a/src/mongo/s/write_ops/batched_request_metadata.h
+++ b/src/mongo/s/write_ops/batched_request_metadata.h
@@ -28,33 +28,34 @@
#pragma once
-#include <boost/optional.hpp>
#include <string>
+#include "mongo/base/disallow_copying.h"
#include "mongo/db/jsobj.h"
#include "mongo/s/bson_serializable.h"
#include "mongo/s/chunk_version.h"
namespace mongo {
+class BatchedRequestMetadata : public BSONSerializable {
+ MONGO_DISALLOW_COPYING(BatchedRequestMetadata);
-class BatchedRequestMetadata {
public:
static const BSONField<std::string> shardName;
static const BSONField<ChunkVersion> shardVersion;
static const BSONField<long long> session;
BatchedRequestMetadata();
- ~BatchedRequestMetadata();
+ virtual ~BatchedRequestMetadata();
//
// bson serializable interface implementation
//
- bool isValid(std::string* errMsg) const;
- BSONObj toBSON() const;
- bool parseBSON(const BSONObj& source, std::string* errMsg);
- void clear();
- std::string toString() const;
+ virtual bool isValid(std::string* errMsg) const;
+ virtual BSONObj toBSON() const;
+ virtual bool parseBSON(const BSONObj& source, std::string* errMsg);
+ virtual void clear();
+ virtual std::string toString() const;
void cloneTo(BatchedRequestMetadata* other) const;
@@ -63,12 +64,14 @@ public:
//
void setShardName(StringData shardName);
+ void unsetShardName();
+ bool isShardNameSet() const;
const std::string& getShardName() const;
- void setShardVersion(const ChunkVersionAndOpTime& shardVersion);
+ void setShardVersion(const ChunkVersion& shardVersion);
+ void unsetShardVersion();
bool isShardVersionSet() const;
const ChunkVersion& getShardVersion() const;
- const repl::OpTime& getOpTime() const;
void setSession(long long session);
void unsetSession();
@@ -81,11 +84,10 @@ private:
bool _isShardNameSet;
// (O) version for this collection on a given shard
- boost::optional<ChunkVersionAndOpTime> _shardVersion;
+ std::unique_ptr<ChunkVersion> _shardVersion;
// (O) session number the inserts belong to
long long _session;
bool _isSessionSet;
};
-
-} // namespace mongo
+}
diff --git a/src/mongo/s/write_ops/batched_request_metadata_test.cpp b/src/mongo/s/write_ops/batched_request_metadata_test.cpp
index 978ee865045..f35bcee4ef9 100644
--- a/src/mongo/s/write_ops/batched_request_metadata_test.cpp
+++ b/src/mongo/s/write_ops/batched_request_metadata_test.cpp
@@ -40,16 +40,22 @@ using std::string;
namespace {
TEST(BatchedRequestMetadata, Basic) {
- BSONObj metadataObj(BSON("shardName"
- << "shard0000"
- << "shardVersion" << BSON_ARRAY(Timestamp(1, 2) << OID::gen()) << "ts"
- << Timestamp(3, 4) << "t" << 5 << "session" << 0LL));
+ // The BSON_ARRAY macro doesn't support Timestamps.
+ BSONArrayBuilder arrBuilder;
+ arrBuilder.append(Timestamp(1, 1));
+ arrBuilder.append(OID::gen());
+ BSONArray shardVersionArray = arrBuilder.arr();
+
+ BSONObj metadataObj(BSON(BatchedRequestMetadata::shardName("shard0000")
+ << BatchedRequestMetadata::shardVersion() << shardVersionArray
+ << BatchedRequestMetadata::session(100)));
string errMsg;
BatchedRequestMetadata metadata;
ASSERT_TRUE(metadata.parseBSON(metadataObj, &errMsg));
- ASSERT_EQUALS(metadataObj, metadata.toBSON());
+ BSONObj genMetadataObj = metadata.toBSON();
+ ASSERT_EQUALS(metadataObj, genMetadataObj);
}
} // namespace
diff --git a/src/mongo/s/write_ops/batched_update_request_test.cpp b/src/mongo/s/write_ops/batched_update_request_test.cpp
index af7bb5aadfb..04994733537 100644
--- a/src/mongo/s/write_ops/batched_update_request_test.cpp
+++ b/src/mongo/s/write_ops/batched_update_request_test.cpp
@@ -50,24 +50,32 @@ TEST(BatchedUpdateRequest, Basic) {
<< BatchedUpdateDocument::updateExpr(BSON("$set" << BSON("b" << 2)))
<< BatchedUpdateDocument::multi(false) << BatchedUpdateDocument::upsert(false)));
- BSONObj origUpdateRequestObj = BSON(
- BatchedUpdateRequest::collName("test")
- << BatchedUpdateRequest::updates() << updateArray
- << BatchedUpdateRequest::writeConcern(BSON("w" << 1)) << BatchedUpdateRequest::ordered(true)
- << BatchedUpdateRequest::metadata() << BSON("shardName"
- << "shard000"
- << "shardVersion"
- << BSON_ARRAY(Timestamp(1, 2) << OID::gen())
- << "ts" << Timestamp(3, 4) << "t" << 5
- << "session" << 0LL));
+ BSONObj writeConcernObj = BSON("w" << 1);
+
+ // The BSON_ARRAY macro doesn't support Timestamps.
+ BSONArrayBuilder arrBuilder;
+ arrBuilder.append(Timestamp(1, 1));
+ arrBuilder.append(OID::gen());
+ BSONArray shardVersionArray = arrBuilder.arr();
+
+ BSONObj origUpdateRequestObj =
+ BSON(BatchedUpdateRequest::collName("test")
+ << BatchedUpdateRequest::updates() << updateArray
+ << BatchedUpdateRequest::writeConcern(writeConcernObj)
+ << BatchedUpdateRequest::ordered(true) << BatchedUpdateRequest::metadata()
+ << BSON(BatchedRequestMetadata::shardName("shard0000")
+ << BatchedRequestMetadata::shardVersion() << shardVersionArray
+ << BatchedRequestMetadata::session(0)));
string errMsg;
BatchedUpdateRequest request;
- ASSERT_TRUE(request.parseBSON("foo", origUpdateRequestObj, &errMsg));
+ bool ok = request.parseBSON("foo", origUpdateRequestObj, &errMsg);
+ ASSERT_TRUE(ok);
ASSERT_EQ("foo.test", request.getNS().ns());
- ASSERT_EQUALS(origUpdateRequestObj, request.toBSON());
+ BSONObj genUpdateRequestObj = request.toBSON();
+ ASSERT_EQUALS(0, genUpdateRequestObj.woCompare(origUpdateRequestObj));
}
} // namespace
diff --git a/src/mongo/s/write_ops/write_op.cpp b/src/mongo/s/write_ops/write_op.cpp
index 8cd20fa4865..25f9f13b3aa 100644
--- a/src/mongo/s/write_ops/write_op.cpp
+++ b/src/mongo/s/write_ops/write_op.cpp
@@ -127,8 +127,7 @@ Status WriteOp::targetWrites(OperationContext* txn,
if (endpoints.size() == 1u) {
targetedWrites->push_back(new TargetedWrite(*endpoint, ref));
} else {
- ShardEndpoint broadcastEndpoint(endpoint->shardName,
- ChunkVersionAndOpTime(ChunkVersion::IGNORED()));
+ ShardEndpoint broadcastEndpoint(endpoint->shardName, ChunkVersion::IGNORED());
targetedWrites->push_back(new TargetedWrite(broadcastEndpoint, ref));
}
diff --git a/src/mongo/s/write_ops/write_op_test.cpp b/src/mongo/s/write_ops/write_op_test.cpp
index 233aa824337..e488c068e47 100644
--- a/src/mongo/s/write_ops/write_op_test.cpp
+++ b/src/mongo/s/write_ops/write_op_test.cpp
@@ -218,11 +218,11 @@ TEST(WriteOpTests, TargetMultiAllShards) {
ASSERT_EQUALS(targeted.size(), 3u);
sortByEndpoint(&targeted);
ASSERT_EQUALS(targeted[0]->endpoint.shardName, endpointA.shardName);
- ASSERT(ChunkVersion::isIgnoredVersion(targeted[0]->endpoint.shardVersion.getVersion()));
+ ASSERT(ChunkVersion::isIgnoredVersion(targeted[0]->endpoint.shardVersion));
ASSERT_EQUALS(targeted[1]->endpoint.shardName, endpointB.shardName);
- ASSERT(ChunkVersion::isIgnoredVersion(targeted[1]->endpoint.shardVersion.getVersion()));
+ ASSERT(ChunkVersion::isIgnoredVersion(targeted[1]->endpoint.shardVersion));
ASSERT_EQUALS(targeted[2]->endpoint.shardName, endpointC.shardName);
- ASSERT(ChunkVersion::isIgnoredVersion(targeted[2]->endpoint.shardVersion.getVersion()));
+ ASSERT(ChunkVersion::isIgnoredVersion(targeted[2]->endpoint.shardVersion));
writeOp.noteWriteComplete(*targeted[0]);
writeOp.noteWriteComplete(*targeted[1]);