summaryrefslogtreecommitdiff
path: root/src/mongo/db/s
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2016-10-11 17:05:02 -0400
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2016-10-18 15:58:56 -0400
commita0fd9c9714cdcd6be7eae05c31a578c17ed6d780 (patch)
tree0d105fa6a407c40bdbf106668c48b3e63cbb799e /src/mongo/db/s
parentcc8e8a138b7116ddd2b6eff56da2f4219262e837 (diff)
downloadmongo-a0fd9c9714cdcd6be7eae05c31a578c17ed6d780.tar.gz
SERVER-25665 Persist chunk version as part of the active migration document
Diffstat (limited to 'src/mongo/db/s')
-rw-r--r--src/mongo/db/s/balancer/balancer.cpp7
-rw-r--r--src/mongo/db/s/balancer/balancer_chunk_selection_policy_impl.cpp1
-rw-r--r--src/mongo/db/s/balancer/balancer_policy.cpp27
-rw-r--r--src/mongo/db/s/balancer/balancer_policy.h24
-rw-r--r--src/mongo/db/s/balancer/balancer_policy_test.cpp15
-rw-r--r--src/mongo/db/s/balancer/migration_manager_test.cpp87
-rw-r--r--src/mongo/db/s/balancer/scoped_migration_request.cpp3
-rw-r--r--src/mongo/db/s/balancer/scoped_migration_request_test.cpp2
-rw-r--r--src/mongo/db/s/balancer/type_migration.cpp54
-rw-r--r--src/mongo/db/s/balancer/type_migration.h15
-rw-r--r--src/mongo/db/s/balancer/type_migration_test.cpp37
11 files changed, 155 insertions, 117 deletions
diff --git a/src/mongo/db/s/balancer/balancer.cpp b/src/mongo/db/s/balancer/balancer.cpp
index 1cc7d850ada..d2d6f3cc261 100644
--- a/src/mongo/db/s/balancer/balancer.cpp
+++ b/src/mongo/db/s/balancer/balancer.cpp
@@ -275,11 +275,8 @@ Status Balancer::moveSingleChunk(OperationContext* txn,
return moveAllowedStatus;
}
- return _migrationManager.executeManualMigration(txn,
- MigrateInfo(chunk.getNS(), newShardId, chunk),
- maxChunkSizeBytes,
- secondaryThrottle,
- waitForDelete);
+ return _migrationManager.executeManualMigration(
+ txn, MigrateInfo(newShardId, chunk), maxChunkSizeBytes, secondaryThrottle, waitForDelete);
}
void Balancer::report(OperationContext* txn, BSONObjBuilder* builder) {
diff --git a/src/mongo/db/s/balancer/balancer_chunk_selection_policy_impl.cpp b/src/mongo/db/s/balancer/balancer_chunk_selection_policy_impl.cpp
index 2dc4f48bddf..ef688f73dab 100644
--- a/src/mongo/db/s/balancer/balancer_chunk_selection_policy_impl.cpp
+++ b/src/mongo/db/s/balancer/balancer_chunk_selection_policy_impl.cpp
@@ -76,6 +76,7 @@ StatusWith<DistributionStatus> createCollectionDistributionStatus(
const auto& chunkEntry = entry.second;
ChunkType chunk;
+ chunk.setNS(chunkMgr->getns());
chunk.setMin(chunkEntry->getMin());
chunk.setMax(chunkEntry->getMax());
chunk.setJumbo(chunkEntry->isJumbo());
diff --git a/src/mongo/db/s/balancer/balancer_policy.cpp b/src/mongo/db/s/balancer/balancer_policy.cpp
index 5b53cfc0320..ea8365f6524 100644
--- a/src/mongo/db/s/balancer/balancer_policy.cpp
+++ b/src/mongo/db/s/balancer/balancer_policy.cpp
@@ -143,7 +143,8 @@ Status DistributionStatus::addRangeToZone(const ZoneRange& range) {
}
}
- _zoneRanges[range.max.getOwned()] = range;
+ // This must be a new entry
+ _zoneRanges.emplace(range.max.getOwned(), range);
_allTags.insert(range.zone);
return Status::OK();
}
@@ -337,7 +338,7 @@ vector<MigrateInfo> BalancerPolicy::balance(const ShardStatisticsVector& shardSt
}
invariant(to != stat.shardId);
- migrations.emplace_back(distribution.nss().ns(), to, chunk);
+ migrations.emplace_back(to, chunk);
invariant(usedShards.insert(stat.shardId).second);
invariant(usedShards.insert(to).second);
break;
@@ -384,7 +385,7 @@ vector<MigrateInfo> BalancerPolicy::balance(const ShardStatisticsVector& shardSt
}
invariant(to != stat.shardId);
- migrations.emplace_back(distribution.nss().ns(), to, chunk);
+ migrations.emplace_back(to, chunk);
invariant(usedShards.insert(stat.shardId).second);
invariant(usedShards.insert(to).second);
break;
@@ -421,7 +422,7 @@ boost::optional<MigrateInfo> BalancerPolicy::balanceSingleChunk(
return boost::optional<MigrateInfo>();
}
- return MigrateInfo(distribution.nss().ns(), newShardId, chunk);
+ return MigrateInfo(newShardId, chunk);
}
bool BalancerPolicy::_singleZoneBalance(const ShardStatisticsVector& shardStats,
@@ -500,7 +501,7 @@ bool BalancerPolicy::_singleZoneBalance(const ShardStatisticsVector& shardStats,
continue;
}
- migrations->emplace_back(distribution.nss().ns(), to, chunk);
+ migrations->emplace_back(to, chunk);
invariant(usedShards->insert(chunk.getShard()).second);
invariant(usedShards->insert(to).second);
return true;
@@ -515,10 +516,26 @@ bool BalancerPolicy::_singleZoneBalance(const ShardStatisticsVector& shardStats,
return false;
}
+ZoneRange::ZoneRange(const BSONObj& a_min, const BSONObj& a_max, const std::string& _zone)
+ : min(a_min.getOwned()), max(a_max.getOwned()), zone(_zone) {}
+
string ZoneRange::toString() const {
return str::stream() << min << " -->> " << max << " on " << zone;
}
+MigrateInfo::MigrateInfo(const ShardId& a_to, const ChunkType& a_chunk) {
+ invariantOK(a_chunk.validate());
+ invariant(a_to.isValid());
+
+ to = a_to;
+
+ ns = a_chunk.getNS();
+ from = a_chunk.getShard();
+ minKey = a_chunk.getMin();
+ maxKey = a_chunk.getMax();
+ version = a_chunk.getVersion();
+}
+
std::string MigrateInfo::getName() const {
return ChunkType::genID(ns, minKey);
}
diff --git a/src/mongo/db/s/balancer/balancer_policy.h b/src/mongo/db/s/balancer/balancer_policy.h
index c1438ba995e..c08aee77ceb 100644
--- a/src/mongo/db/s/balancer/balancer_policy.h
+++ b/src/mongo/db/s/balancer/balancer_policy.h
@@ -37,14 +37,8 @@
namespace mongo {
-class ChunkManager;
-class OperationContext;
-
struct ZoneRange {
- ZoneRange() = default;
-
- ZoneRange(const BSONObj& a_min, const BSONObj& a_max, const std::string& _zone)
- : min(a_min.getOwned()), max(a_max.getOwned()), zone(_zone) {}
+ ZoneRange(const BSONObj& a_min, const BSONObj& a_max, const std::string& _zone);
std::string toString() const;
@@ -54,21 +48,10 @@ struct ZoneRange {
};
struct MigrateInfo {
- MigrateInfo(const std::string& a_ns, const ShardId& a_to, const ChunkType& a_chunk)
- : ns(a_ns),
- to(a_to),
- from(a_chunk.getShard()),
- minKey(a_chunk.getMin()),
- maxKey(a_chunk.getMax()) {}
-
- MigrateInfo(const std::string& a_ns,
- const ShardId& a_to,
- const ShardId& a_from,
- const BSONObj& a_minKey,
- const BSONObj& a_maxKey)
- : ns(a_ns), to(a_to), from(a_from), minKey(a_minKey), maxKey(a_maxKey) {}
+ MigrateInfo(const ShardId& a_to, const ChunkType& a_chunk);
std::string getName() const;
+
std::string toString() const;
std::string ns;
@@ -76,6 +59,7 @@ struct MigrateInfo {
ShardId from;
BSONObj minKey;
BSONObj maxKey;
+ ChunkVersion version;
};
typedef std::vector<ClusterStatistics::ShardStatistics> ShardStatisticsVector;
diff --git a/src/mongo/db/s/balancer/balancer_policy_test.cpp b/src/mongo/db/s/balancer/balancer_policy_test.cpp
index 35da7c7bf7f..86258c723d8 100644
--- a/src/mongo/db/s/balancer/balancer_policy_test.cpp
+++ b/src/mongo/db/s/balancer/balancer_policy_test.cpp
@@ -30,6 +30,7 @@
#include "mongo/platform/basic.h"
+#include "mongo/db/keypattern.h"
#include "mongo/db/s/balancer/balancer_policy.h"
#include "mongo/platform/random.h"
#include "mongo/s/catalog/type_chunk.h"
@@ -76,6 +77,10 @@ std::pair<ShardStatisticsVector, ShardToChunksMap> generateCluster(
int64_t currentChunk = 0;
+ ChunkVersion chunkVersion(1, 0, OID::gen());
+
+ const KeyPattern shardKeyPattern(BSON("x" << 1));
+
for (auto it = shardsAndNumChunks.begin(); it != shardsAndNumChunks.end(); it++) {
ShardStatistics shard = std::move(it->first);
const size_t numChunks = it->second;
@@ -85,10 +90,16 @@ std::pair<ShardStatisticsVector, ShardToChunksMap> generateCluster(
for (size_t i = 0; i < numChunks; i++, currentChunk++) {
ChunkType chunk;
- chunk.setMin(currentChunk == 0 ? kMinBSONKey : BSON("x" << currentChunk));
- chunk.setMax(currentChunk == totalNumChunks - 1 ? kMaxBSONKey
+
+ chunk.setNS(kNamespace.ns());
+ chunk.setMin(currentChunk == 0 ? shardKeyPattern.globalMin()
+ : BSON("x" << currentChunk));
+ chunk.setMax(currentChunk == totalNumChunks - 1 ? shardKeyPattern.globalMax()
: BSON("x" << currentChunk + 1));
chunk.setShard(shard.shardId);
+ chunk.setVersion(chunkVersion);
+
+ chunkVersion.incMajor();
chunkMap[shard.shardId].push_back(std::move(chunk));
}
diff --git a/src/mongo/db/s/balancer/migration_manager_test.cpp b/src/mongo/db/s/balancer/migration_manager_test.cpp
index 87353c5dc4b..41e2f6419d0 100644
--- a/src/mongo/db/s/balancer/migration_manager_test.cpp
+++ b/src/mongo/db/s/balancer/migration_manager_test.cpp
@@ -113,11 +113,7 @@ protected:
/**
* Inserts a document into the config.migrations collection as an active migration.
*/
- void setUpMigration(const std::string& collName,
- const BSONObj& minKey,
- const BSONObj& maxKey,
- const ShardId& toShard,
- const ShardId& fromShard);
+ void setUpMigration(const ChunkType& chunk, const ShardId& toShard);
/**
* Asserts that config.migrations is empty and config.locks contains no locked documents, both
@@ -219,17 +215,15 @@ ChunkType MigrationManagerTest::setUpChunk(const std::string& collName,
return chunk;
}
-void MigrationManagerTest::setUpMigration(const std::string& collName,
- const BSONObj& minKey,
- const BSONObj& maxKey,
- const ShardId& toShard,
- const ShardId& fromShard) {
+void MigrationManagerTest::setUpMigration(const ChunkType& chunk, const ShardId& toShard) {
BSONObjBuilder builder;
- builder.append(MigrationType::ns(), collName);
- builder.append(MigrationType::min(), minKey);
- builder.append(MigrationType::max(), maxKey);
+ builder.append(MigrationType::ns(), chunk.getNS());
+ builder.append(MigrationType::min(), chunk.getMin());
+ builder.append(MigrationType::max(), chunk.getMax());
builder.append(MigrationType::toShard(), toShard.toString());
- builder.append(MigrationType::fromShard(), fromShard.toString());
+ builder.append(MigrationType::fromShard(), chunk.getShard().toString());
+ chunk.getVersion().appendWithFieldForCommands(&builder, "chunkVersion");
+
MigrationType migrationType = assertGet(MigrationType::fromBSON(builder.obj()));
ASSERT_OK(catalogClient()->insertConfigDocument(operationContext(),
MigrationType::ConfigNS,
@@ -319,8 +313,7 @@ TEST_F(MigrationManagerTest, OneCollectionTwoMigrations) {
setUpChunk(collName, BSON(kPattern << 49), kKeyPattern.globalMax(), kShardId2, version);
// Going to request that these two chunks get migrated.
- const std::vector<MigrateInfo> migrationRequests{{chunk1.getNS(), kShardId1, chunk1},
- {chunk2.getNS(), kShardId3, chunk2}};
+ const std::vector<MigrateInfo> migrationRequests{{kShardId1, chunk1}, {kShardId3, chunk2}};
auto future = launchAsync([this, migrationRequests] {
Client::initThreadIfNotAlready("Test");
@@ -379,10 +372,10 @@ TEST_F(MigrationManagerTest, TwoCollectionsTwoMigrationsEach) {
setUpChunk(collName2, BSON(kPattern << 49), kKeyPattern.globalMax(), kShardId2, version2);
// Going to request that these four chunks get migrated.
- const std::vector<MigrateInfo> migrationRequests{{chunk1coll1.getNS(), kShardId1, chunk1coll1},
- {chunk2coll1.getNS(), kShardId3, chunk2coll1},
- {chunk1coll2.getNS(), kShardId1, chunk1coll2},
- {chunk2coll2.getNS(), kShardId3, chunk2coll2}};
+ const std::vector<MigrateInfo> migrationRequests{{kShardId1, chunk1coll1},
+ {kShardId3, chunk2coll1},
+ {kShardId1, chunk1coll2},
+ {kShardId3, chunk2coll2}};
auto future = launchAsync([this, migrationRequests] {
Client::initThreadIfNotAlready("Test");
@@ -437,8 +430,7 @@ TEST_F(MigrationManagerTest, SameCollectionOldShardMigration) {
setUpChunk(collName, BSON(kPattern << 49), kKeyPattern.globalMax(), kShardId2, version);
// Going to request that these two chunks get migrated.
- const std::vector<MigrateInfo> migrationRequests{{chunk1.getNS(), kShardId1, chunk1},
- {chunk2.getNS(), kShardId3, chunk2}};
+ const std::vector<MigrateInfo> migrationRequests{{kShardId1, chunk1}, {kShardId3, chunk2}};
auto future = launchAsync([this, migrationRequests] {
Client::initThreadIfNotAlready("Test");
@@ -491,7 +483,7 @@ TEST_F(MigrationManagerTest, SameOldShardFailsToAcquireDistributedLockTwice) {
setUpChunk(collName, kKeyPattern.globalMin(), kKeyPattern.globalMax(), kShardId0, version);
// Going to request that this chunk get migrated.
- const std::vector<MigrateInfo> migrationRequests{{chunk1.getNS(), kShardId1, chunk1}};
+ const std::vector<MigrateInfo> migrationRequests{{kShardId1, chunk1}};
auto future = launchAsync([this, migrationRequests] {
Client::initThreadIfNotAlready("Test");
@@ -550,8 +542,7 @@ TEST_F(MigrationManagerTest, SameCollectionTwoOldShardMigrations) {
setUpChunk(collName, BSON(kPattern << 49), kKeyPattern.globalMax(), kShardId2, version);
// Going to request that these two chunks get migrated.
- const std::vector<MigrateInfo> migrationRequests{{chunk1.getNS(), kShardId1, chunk1},
- {chunk2.getNS(), kShardId3, chunk2}};
+ const std::vector<MigrateInfo> migrationRequests{{kShardId1, chunk1}, {kShardId3, chunk2}};
auto future = launchAsync([this, migrationRequests] {
Client::initThreadIfNotAlready("Test");
@@ -614,8 +605,7 @@ TEST_F(MigrationManagerTest, FailToAcquireDistributedLock) {
setUpChunk(collName, BSON(kPattern << 49), kKeyPattern.globalMax(), kShardId2, version);
// Going to request that these two chunks get migrated.
- const std::vector<MigrateInfo> migrationRequests{{chunk1.getNS(), kShardId1, chunk1},
- {chunk2.getNS(), kShardId3, chunk2}};
+ const std::vector<MigrateInfo> migrationRequests{{kShardId1, chunk1}, {kShardId3, chunk2}};
shardTargeterMock(operationContext(), kShardId0)->setFindHostReturnValue(kShardHost0);
shardTargeterMock(operationContext(), kShardId2)->setFindHostReturnValue(kShardHost2);
@@ -662,8 +652,7 @@ TEST_F(MigrationManagerTest, SourceShardNotFound) {
setUpChunk(collName, BSON(kPattern << 49), kKeyPattern.globalMax(), kShardId2, version);
// Going to request that these two chunks get migrated.
- const std::vector<MigrateInfo> migrationRequests{{chunk1.getNS(), kShardId1, chunk1},
- {chunk2.getNS(), kShardId3, chunk2}};
+ const std::vector<MigrateInfo> migrationRequests{{kShardId1, chunk1}, {kShardId3, chunk2}};
auto future = launchAsync([this, chunk1, chunk2, migrationRequests] {
Client::initThreadIfNotAlready("Test");
@@ -708,7 +697,7 @@ TEST_F(MigrationManagerTest, JumboChunkResponseBackwardsCompatibility) {
setUpChunk(collName, kKeyPattern.globalMin(), kKeyPattern.globalMax(), kShardId0, version);
// Going to request that this chunk gets migrated.
- const std::vector<MigrateInfo> migrationRequests{{chunk1.getNS(), kShardId1, chunk1}};
+ const std::vector<MigrateInfo> migrationRequests{{kShardId1, chunk1}};
auto future = launchAsync([this, chunk1, migrationRequests] {
Client::initThreadIfNotAlready("Test");
@@ -757,7 +746,7 @@ TEST_F(MigrationManagerTest, InterruptMigration) {
shardTargeterMock(txn.get(), kShardId0)->setFindHostReturnValue(kShardHost0);
ASSERT_NOT_OK(_migrationManager->executeManualMigration(
- txn.get(), {chunk.getNS(), kShardId1, chunk}, 0, kDefaultSecondaryThrottle, false));
+ txn.get(), {kShardId1, chunk}, 0, kDefaultSecondaryThrottle, false));
});
// Wait till the move chunk request gets sent and pretend that it is stuck by never responding
@@ -779,11 +768,8 @@ TEST_F(MigrationManagerTest, InterruptMigration) {
future.timed_get(kFutureTimeout);
// Ensure that no new migrations can be scheduled
- ASSERT_NOT_OK(_migrationManager->executeManualMigration(operationContext(),
- {chunk.getNS(), kShardId1, chunk},
- 0,
- kDefaultSecondaryThrottle,
- false));
+ ASSERT_NOT_OK(_migrationManager->executeManualMigration(
+ operationContext(), {kShardId1, chunk}, 0, kDefaultSecondaryThrottle, false));
// Ensure that the migration manager is no longer handling any migrations.
_migrationManager->drainActiveMigrations();
@@ -846,7 +832,7 @@ TEST_F(MigrationManagerTest, RestartMigrationManager) {
shardTargeterMock(txn.get(), kShardId0)->setFindHostReturnValue(kShardHost0);
ASSERT_OK(_migrationManager->executeManualMigration(
- txn.get(), {chunk1.getNS(), kShardId1, chunk1}, 0, kDefaultSecondaryThrottle, false));
+ txn.get(), {kShardId1, chunk1}, 0, kDefaultSecondaryThrottle, false));
});
// Expect only one moveChunk command to be called.
@@ -866,12 +852,13 @@ TEST_F(MigrationManagerTest, MigrationRecovery) {
// Set up the database and collection as sharded in the metadata.
std::string dbName = "foo";
std::string collName = "foo.bar";
- ChunkVersion version(2, 0, OID::gen());
+ ChunkVersion version(1, 0, OID::gen());
setUpDatabase(dbName, kShardId0);
setUpCollection(collName, version);
- // Set up two chunks in the metadata.
+ // Set up two chunks in the metadata and set up two fake active migrations by writing documents
+ // to the config.migrations collection.
ChunkType chunk1 =
setUpChunk(collName, kKeyPattern.globalMin(), BSON(kPattern << 49), kShardId0, version);
version.incMinor();
@@ -881,17 +868,8 @@ TEST_F(MigrationManagerTest, MigrationRecovery) {
_migrationManager->interruptAndDisableMigrations();
_migrationManager->drainActiveMigrations();
- // Set up two fake active migrations by writing documents to the config.migrations collection.
- setUpMigration(collName,
- chunk1.getMin(),
- chunk1.getMax(),
- kShardId1.toString(),
- chunk1.getShard().toString());
- setUpMigration(collName,
- chunk2.getMin(),
- chunk2.getMax(),
- kShardId3.toString(),
- chunk2.getShard().toString());
+ setUpMigration(chunk1, kShardId1.toString());
+ setUpMigration(chunk2, kShardId3.toString());
_migrationManager->startRecoveryAndAcquireDistLocks(operationContext());
@@ -925,7 +903,7 @@ TEST_F(MigrationManagerTest, FailMigrationRecovery) {
// Set up the database and collection as sharded in the metadata.
std::string dbName = "foo";
std::string collName = "foo.bar";
- ChunkVersion version(2, 0, OID::gen());
+ ChunkVersion version(1, 0, OID::gen());
setUpDatabase(dbName, kShardId0);
setUpCollection(collName, version);
@@ -940,12 +918,7 @@ TEST_F(MigrationManagerTest, FailMigrationRecovery) {
_migrationManager->interruptAndDisableMigrations();
_migrationManager->drainActiveMigrations();
- // Set up a parsable fake active migration document in the config.migrations collection.
- setUpMigration(collName,
- chunk1.getMin(),
- chunk1.getMax(),
- kShardId1.toString(),
- chunk1.getShard().toString());
+ setUpMigration(chunk1, kShardId1.toString());
// Set up a fake active migration document that will fail MigrationType parsing -- missing
// field.
diff --git a/src/mongo/db/s/balancer/scoped_migration_request.cpp b/src/mongo/db/s/balancer/scoped_migration_request.cpp
index ebc3e293814..fc4667c1f0c 100644
--- a/src/mongo/db/s/balancer/scoped_migration_request.cpp
+++ b/src/mongo/db/s/balancer/scoped_migration_request.cpp
@@ -95,7 +95,8 @@ StatusWith<ScopedMigrationRequest> ScopedMigrationRequest::writeMigration(
OperationContext* txn, const MigrateInfo& migrateInfo) {
// Try to write a unique migration document to config.migrations.
- MigrationType migrationType(migrateInfo);
+ const MigrationType migrationType(migrateInfo);
+
for (int retry = 0; retry < kDuplicateKeyErrorMaxRetries; ++retry) {
Status result = grid.catalogClient(txn)->insertConfigDocument(
txn, MigrationType::ConfigNS, migrationType.toBSON(), kMajorityWriteConcern);
diff --git a/src/mongo/db/s/balancer/scoped_migration_request_test.cpp b/src/mongo/db/s/balancer/scoped_migration_request_test.cpp
index 0b6474eaa46..7e870c0ae49 100644
--- a/src/mongo/db/s/balancer/scoped_migration_request_test.cpp
+++ b/src/mongo/db/s/balancer/scoped_migration_request_test.cpp
@@ -104,7 +104,7 @@ MigrateInfo makeMigrateInfo() {
ChunkType chunkType = assertGet(ChunkType::fromBSON(chunkBuilder.obj()));
ASSERT_OK(chunkType.validate());
- return MigrateInfo(kNs, kToShard, chunkType);
+ return MigrateInfo(kToShard, chunkType);
}
TEST_F(ScopedMigrationRequestTest, CreateScopedMigrationRequest) {
diff --git a/src/mongo/db/s/balancer/type_migration.cpp b/src/mongo/db/s/balancer/type_migration.cpp
index 6dd2fe50c23..a9a3a9c6ffc 100644
--- a/src/mongo/db/s/balancer/type_migration.cpp
+++ b/src/mongo/db/s/balancer/type_migration.cpp
@@ -34,6 +34,11 @@
#include "mongo/s/catalog/type_chunk.h"
namespace mongo {
+namespace {
+
+const StringData kChunkVersion = "chunkVersion"_sd;
+
+} // namespace
const std::string MigrationType::ConfigNS = "config.migrations";
@@ -51,7 +56,8 @@ MigrationType::MigrationType(MigrateInfo info)
_min(info.minKey),
_max(info.maxKey),
_fromShard(info.from),
- _toShard(info.to) {}
+ _toShard(info.to),
+ _chunkVersion(info.version) {}
StatusWith<MigrationType> MigrationType::fromBSON(const BSONObj& source) {
MigrationType migrationType;
@@ -79,7 +85,7 @@ StatusWith<MigrationType> MigrationType::fromBSON(const BSONObj& source) {
Status status = bsonExtractStringField(source, toShard.name(), &migrationToShard);
if (!status.isOK())
return status;
- migrationType._toShard = migrationToShard;
+ migrationType._toShard = std::move(migrationToShard);
}
{
@@ -87,7 +93,15 @@ StatusWith<MigrationType> MigrationType::fromBSON(const BSONObj& source) {
Status status = bsonExtractStringField(source, fromShard.name(), &migrationFromShard);
if (!status.isOK())
return status;
- migrationType._fromShard = migrationFromShard;
+ migrationType._fromShard = std::move(migrationFromShard);
+ }
+
+ {
+ auto chunkVersionStatus =
+ ChunkVersion::parseFromBSONWithFieldForCommands(source, kChunkVersion);
+ if (!chunkVersionStatus.isOK())
+ return chunkVersionStatus.getStatus();
+ migrationType._chunkVersion = chunkVersionStatus.getValue();
}
return migrationType;
@@ -95,28 +109,34 @@ StatusWith<MigrationType> MigrationType::fromBSON(const BSONObj& source) {
BSONObj MigrationType::toBSON() const {
BSONObjBuilder builder;
- if (_nss && _min)
- builder.append(name.name(), getName());
- if (_nss)
- builder.append(ns.name(), _nss->ns());
- if (_min)
- builder.append(min.name(), _min.get());
- if (_max)
- builder.append(max.name(), _max.get());
- if (_fromShard)
- builder.append(fromShard.name(), _fromShard->toString());
- if (_toShard)
- builder.append(toShard.name(), _toShard->toString());
+
+ builder.append(name.name(), getName());
+ builder.append(ns.name(), _nss.ns());
+
+ builder.append(min.name(), _min);
+ builder.append(max.name(), _max);
+
+ builder.append(fromShard.name(), _fromShard.toString());
+ builder.append(toShard.name(), _toShard.toString());
+
+ _chunkVersion.appendWithFieldForCommands(&builder, kChunkVersion);
return builder.obj();
}
MigrateInfo MigrationType::toMigrateInfo() const {
- return MigrateInfo(_nss->ns(), _toShard.get(), _fromShard.get(), _min.get(), _max.get());
+ ChunkType chunk;
+ chunk.setNS(_nss.ns());
+ chunk.setShard(_fromShard);
+ chunk.setMin(_min);
+ chunk.setMax(_max);
+ chunk.setVersion(_chunkVersion);
+
+ return MigrateInfo(_toShard, chunk);
}
std::string MigrationType::getName() const {
- return ChunkType::genID(_nss->ns(), _min.get());
+ return ChunkType::genID(_nss.ns(), _min);
}
} // namespace mongo
diff --git a/src/mongo/db/s/balancer/type_migration.h b/src/mongo/db/s/balancer/type_migration.h
index 41d6ed72f48..bf741e30f3d 100644
--- a/src/mongo/db/s/balancer/type_migration.h
+++ b/src/mongo/db/s/balancer/type_migration.h
@@ -52,8 +52,6 @@ public:
static const BSONField<BSONObj> max;
static const BSONField<std::string> fromShard;
static const BSONField<std::string> toShard;
- static const BSONField<std::string> chunkVersionField;
- static const BSONField<std::string> collectionVersionField;
/**
* The Balancer encapsulates migration information in MigrateInfo objects, so this facilitates
@@ -85,12 +83,13 @@ public:
private:
MigrationType();
- // Required fields for config.migrations.
- boost::optional<NamespaceString> _nss;
- boost::optional<BSONObj> _min;
- boost::optional<BSONObj> _max;
- boost::optional<ShardId> _fromShard;
- boost::optional<ShardId> _toShard;
+ // All required fields for config.migrations
+ NamespaceString _nss;
+ BSONObj _min;
+ BSONObj _max;
+ ShardId _fromShard;
+ ShardId _toShard;
+ ChunkVersion _chunkVersion;
};
} // namespace mongo
diff --git a/src/mongo/db/s/balancer/type_migration_test.cpp b/src/mongo/db/s/balancer/type_migration_test.cpp
index ffd0de4127b..eb04d585305 100644
--- a/src/mongo/db/s/balancer/type_migration_test.cpp
+++ b/src/mongo/db/s/balancer/type_migration_test.cpp
@@ -60,7 +60,7 @@ TEST(MigrationTypeTest, ConvertFromMigrationInfo) {
ChunkType chunkType = assertGet(ChunkType::fromBSON(chunkBuilder.obj()));
ASSERT_OK(chunkType.validate());
- MigrateInfo migrateInfo(kNs, kToShard, chunkType);
+ MigrateInfo migrateInfo(kToShard, chunkType);
MigrationType migrationType(migrateInfo);
BSONObjBuilder builder;
@@ -70,6 +70,7 @@ TEST(MigrationTypeTest, ConvertFromMigrationInfo) {
builder.append(MigrationType::max(), kMax);
builder.append(MigrationType::fromShard(), kFromShard.toString());
builder.append(MigrationType::toShard(), kToShard.toString());
+ version.appendWithFieldForCommands(&builder, "chunkVersion");
BSONObj obj = builder.obj();
@@ -77,6 +78,8 @@ TEST(MigrationTypeTest, ConvertFromMigrationInfo) {
}
TEST(MigrationTypeTest, FromAndToBSON) {
+ const ChunkVersion version(1, 2, OID::gen());
+
BSONObjBuilder builder;
builder.append(MigrationType::name(), kName);
builder.append(MigrationType::ns(), kNs);
@@ -84,6 +87,7 @@ TEST(MigrationTypeTest, FromAndToBSON) {
builder.append(MigrationType::max(), kMax);
builder.append(MigrationType::fromShard(), kFromShard.toString());
builder.append(MigrationType::toShard(), kToShard.toString());
+ version.appendWithFieldForCommands(&builder, "chunkVersion");
BSONObj obj = builder.obj();
@@ -92,11 +96,14 @@ TEST(MigrationTypeTest, FromAndToBSON) {
}
TEST(MigrationTypeTest, MissingRequiredNamespaceField) {
+ const ChunkVersion version(1, 2, OID::gen());
+
BSONObjBuilder builder;
builder.append(MigrationType::min(), kMin);
builder.append(MigrationType::max(), kMax);
builder.append(MigrationType::fromShard(), kFromShard.toString());
builder.append(MigrationType::toShard(), kToShard.toString());
+ version.appendWithFieldForCommands(&builder, "chunkVersion");
BSONObj obj = builder.obj();
@@ -106,11 +113,14 @@ TEST(MigrationTypeTest, MissingRequiredNamespaceField) {
}
TEST(MigrationTypeTest, MissingRequiredMinField) {
+ const ChunkVersion version(1, 2, OID::gen());
+
BSONObjBuilder builder;
builder.append(MigrationType::ns(), kNs);
builder.append(MigrationType::max(), kMax);
builder.append(MigrationType::fromShard(), kFromShard.toString());
builder.append(MigrationType::toShard(), kToShard.toString());
+ version.appendWithFieldForCommands(&builder, "chunkVersion");
BSONObj obj = builder.obj();
@@ -120,11 +130,14 @@ TEST(MigrationTypeTest, MissingRequiredMinField) {
}
TEST(MigrationTypeTest, MissingRequiredMaxField) {
+ const ChunkVersion version(1, 2, OID::gen());
+
BSONObjBuilder builder;
builder.append(MigrationType::ns(), kNs);
builder.append(MigrationType::min(), kMin);
builder.append(MigrationType::fromShard(), kFromShard.toString());
builder.append(MigrationType::toShard(), kToShard.toString());
+ version.appendWithFieldForCommands(&builder, "chunkVersion");
BSONObj obj = builder.obj();
@@ -134,11 +147,14 @@ TEST(MigrationTypeTest, MissingRequiredMaxField) {
}
TEST(MigrationTypeTest, MissingRequiredFromShardField) {
+ const ChunkVersion version(1, 2, OID::gen());
+
BSONObjBuilder builder;
builder.append(MigrationType::ns(), kNs);
builder.append(MigrationType::min(), kMin);
builder.append(MigrationType::max(), kMax);
builder.append(MigrationType::toShard(), kToShard.toString());
+ version.appendWithFieldForCommands(&builder, "chunkVersion");
BSONObj obj = builder.obj();
@@ -148,11 +164,14 @@ TEST(MigrationTypeTest, MissingRequiredFromShardField) {
}
TEST(MigrationTypeTest, MissingRequiredToShardField) {
+ const ChunkVersion version(1, 2, OID::gen());
+
BSONObjBuilder builder;
builder.append(MigrationType::ns(), kNs);
builder.append(MigrationType::min(), kMin);
builder.append(MigrationType::max(), kMax);
builder.append(MigrationType::fromShard(), kFromShard.toString());
+ version.appendWithFieldForCommands(&builder, "chunkVersion");
BSONObj obj = builder.obj();
@@ -161,5 +180,21 @@ TEST(MigrationTypeTest, MissingRequiredToShardField) {
ASSERT_STRING_CONTAINS(migrationType.getStatus().reason(), MigrationType::toShard.name());
}
+TEST(MigrationTypeTest, MissingRequiredVersionField) {
+ BSONObjBuilder builder;
+ builder.append(MigrationType::name(), kName);
+ builder.append(MigrationType::ns(), kNs);
+ builder.append(MigrationType::min(), kMin);
+ builder.append(MigrationType::max(), kMax);
+ builder.append(MigrationType::fromShard(), kFromShard.toString());
+ builder.append(MigrationType::toShard(), kToShard.toString());
+
+ BSONObj obj = builder.obj();
+
+ StatusWith<MigrationType> migrationType = MigrationType::fromBSON(obj);
+ ASSERT_EQUALS(migrationType.getStatus(), ErrorCodes::NoSuchKey);
+ ASSERT_STRING_CONTAINS(migrationType.getStatus().reason(), "chunkVersion");
+}
+
} // namespace
} // namespace mongo