summaryrefslogtreecommitdiff
path: root/src/mongo/s/balancer_policy_tests.cpp
diff options
context:
space:
mode:
authorRandolph Tan <randolph@10gen.com>2014-07-28 11:35:11 -0400
committerRandolph Tan <randolph@10gen.com>2014-08-07 19:52:15 -0400
commitc30b981260e26dfeff315b766e2887d4f7404f89 (patch)
tree1920a24df0347024ee79cabd50b035ef82bd8709 /src/mongo/s/balancer_policy_tests.cpp
parent88cc54431e112cd2edaa9042b3b20ba1b10fce82 (diff)
downloadmongo-c30b981260e26dfeff315b766e2887d4f7404f89.tar.gz
SERVER-14506 special top chunk logic can move max chunk to a shard with incompatible tag
Make DistributionStatus store ChunkTypes instead of BSONObj
Diffstat (limited to 'src/mongo/s/balancer_policy_tests.cpp')
-rw-r--r--src/mongo/s/balancer_policy_tests.cpp272
1 files changed, 168 insertions, 104 deletions
diff --git a/src/mongo/s/balancer_policy_tests.cpp b/src/mongo/s/balancer_policy_tests.cpp
index 0bc5470341a..cde493c5876 100644
--- a/src/mongo/s/balancer_policy_tests.cpp
+++ b/src/mongo/s/balancer_policy_tests.cpp
@@ -25,6 +25,7 @@
* then also delete it in the license file.
*/
+#include "mongo/base/owned_pointer_map.h"
#include "mongo/platform/random.h"
#include "mongo/s/balancer_policy.h"
#include "mongo/s/config.h"
@@ -35,6 +36,8 @@ namespace mongo {
namespace {
+ typedef OwnedPointerMap<string, OwnedPointerVector<ChunkType> > OwnedShardToChunksMap;
+
TEST( BalancerPolicyTests , SizeMaxedShardTest ) {
ASSERT( ! ShardInfo( 0, 0, false, false ).isSizeMaxed() );
ASSERT( ! ShardInfo( 100LL, 80LL, false, false ).isSizeMaxed() );
@@ -43,15 +46,21 @@ namespace mongo {
TEST( BalancerPolicyTests , BalanceNormalTest ) {
// 2 chunks and 0 chunk shards
- ShardToChunksMap chunkMap;
- vector<BSONObj> chunks;
- chunks.push_back(BSON(ChunkType::min(BSON("x" << BSON("$minKey"<<1))) <<
- ChunkType::max(BSON("x" << 49))));
- chunks.push_back(BSON(ChunkType::min(BSON("x" << 49)) <<
- ChunkType::max(BSON("x" << BSON("$maxkey"<<1)))));
- chunkMap["shard0"] = chunks;
- chunks.clear();
- chunkMap["shard1"] = chunks;
+ OwnedShardToChunksMap chunkMap;
+ auto_ptr<OwnedPointerVector<ChunkType> > chunks(new OwnedPointerVector<ChunkType>());
+
+ auto_ptr<ChunkType> chunk(new ChunkType());
+ chunk->setMin(BSON("x" << BSON("$minKey" << 1)));
+ chunk->setMax(BSON("x" << 49));
+ chunks->push_back(chunk.release());
+
+ chunk.reset(new ChunkType());
+ chunk->setMin(BSON("x" << 49));
+ chunk->setMax(BSON("x" << BSON("$maxKey" << 1)));
+ chunks->push_back(chunk.release());
+
+ chunkMap.mutableMap()["shard0"] = chunks.release();
+ chunkMap.mutableMap()["shard1"] = new OwnedPointerVector<ChunkType>();
// no limits
ShardInfoMap info;
@@ -59,7 +68,7 @@ namespace mongo {
info["shard1"] = ShardInfo( 0, 0, false, false );
MigrateInfo* c = NULL;
- DistributionStatus status( info, chunkMap );
+ DistributionStatus status(info, chunkMap.map());
c = BalancerPolicy::balance( "ns", status, 1 );
ASSERT( c );
}
@@ -67,25 +76,39 @@ namespace mongo {
TEST( BalancerPolicyTests , BalanceJumbo ) {
// 2 chunks and 0 chunk shards
- ShardToChunksMap chunkMap;
- vector<BSONObj> chunks;
- chunks.push_back(BSON(ChunkType::min(BSON("x" << BSON("$minKey"<<1))) <<
- ChunkType::max(BSON("x" << 10)) <<
- ChunkType::jumbo(true)));
- chunks.push_back(BSON(ChunkType::min(BSON("x" << 10)) <<
- ChunkType::max(BSON("x" << 20)) <<
- ChunkType::jumbo(true)));
- chunks.push_back(BSON(ChunkType::min(BSON("x" << 20)) <<
- ChunkType::max(BSON("x" << 30))));
- chunks.push_back(BSON(ChunkType::min(BSON("x" << 30)) <<
- ChunkType::max(BSON("x" << 40)) <<
- ChunkType::jumbo(true)));
- chunks.push_back(BSON(ChunkType::min(BSON("x" << 40)) <<
- ChunkType::max(BSON("x" << BSON("$maxkey"<<1))) <<
- ChunkType::jumbo(true)));
- chunkMap["shard0"] = chunks;
- chunks.clear();
- chunkMap["shard1"] = chunks;
+ OwnedShardToChunksMap chunkMap;
+ auto_ptr<OwnedPointerVector<ChunkType> > chunks(new OwnedPointerVector<ChunkType>());
+
+ auto_ptr<ChunkType> chunk(new ChunkType());
+ chunk->setMin(BSON("x" << BSON("$minKey" << 1)));
+ chunk->setMax(BSON("x" << 10));
+ chunk->setJumbo(true);
+ chunks->push_back(chunk.release());
+
+ chunk.reset(new ChunkType());
+ chunk->setMin(BSON("x" << 10));
+ chunk->setMax(BSON("x" << 20));
+ chunk->setJumbo(true);
+ chunks->push_back(chunk.release());
+
+ chunk.reset(new ChunkType());
+ chunk->setMin(BSON("x" << 20));
+ chunk->setMax(BSON("x" << 30));
+ chunks->push_back(chunk.release());
+
+ chunk.reset(new ChunkType());
+ chunk->setMin(BSON("x" << 30));
+ chunk->setMax(BSON("x" << 40));
+ chunk->setJumbo(true);
+ chunks->push_back(chunk.release());
+
+ chunk.reset(new ChunkType());
+ chunk->setMin(BSON("x" << 40));
+ chunk->setMax(BSON("x" << BSON("$maxKey" << 1)));
+ chunks->push_back(chunk.release());
+
+ chunkMap.mutableMap()["shard0"] = chunks.release();
+ chunkMap.mutableMap()["shard1"] = new OwnedPointerVector<ChunkType>;
// no limits
ShardInfoMap info;
@@ -93,7 +116,7 @@ namespace mongo {
info["shard1"] = ShardInfo( 0, 0, false, false );
MigrateInfo* c = NULL;
- DistributionStatus status( info, chunkMap );
+ DistributionStatus status(info, chunkMap.map());
c = BalancerPolicy::balance( "ns", status, 1 );
ASSERT( c );
ASSERT_EQUALS( 30, c->chunk.max["x"].numberInt() );
@@ -103,22 +126,28 @@ namespace mongo {
TEST( BalanceNormalTests , BalanceDrainingTest ) {
// one normal, one draining
// 2 chunks and 0 chunk shards
- ShardToChunksMap chunkMap;
- vector<BSONObj> chunks;
- chunks.push_back(BSON(ChunkType::min(BSON("x" << BSON("$minKey"<<1))) <<
- ChunkType::max(BSON("x" << 49))));
- chunkMap["shard0"] = chunks;
- chunks.clear();
- chunks.push_back(BSON(ChunkType::min(BSON("x" << 49))<<
- ChunkType::max(BSON("x" << BSON("$maxkey"<<1)))));
- chunkMap["shard1"] = chunks;
+ OwnedShardToChunksMap chunkMap;
+ auto_ptr<OwnedPointerVector<ChunkType> > chunks(new OwnedPointerVector<ChunkType>());
+
+ auto_ptr<ChunkType> chunk(new ChunkType());
+ chunk->setMin(BSON("x" << BSON("$minKey" << 1)));
+ chunk->setMax(BSON("x" << 49));
+ chunks->push_back(chunk.release());
+
+ chunk.reset(new ChunkType());
+ chunk->setMin(BSON("x" << 49));
+ chunk->setMax(BSON("x" << BSON("$maxKey" << 1)));
+ chunks->push_back(chunk.release());
+
+ chunkMap.mutableMap()["shard0"] = chunks.release();
+ chunkMap.mutableMap()["shard1"] = new OwnedPointerVector<ChunkType>();
// shard0 is draining
ShardInfoMap limitsMap;
limitsMap["shard0"] = ShardInfo( 0LL, 2LL, true, false );
limitsMap["shard1"] = ShardInfo( 0LL, 0LL, false, false );
- DistributionStatus status( limitsMap, chunkMap );
+ DistributionStatus status(limitsMap, chunkMap.map());
MigrateInfo* c = BalancerPolicy::balance( "ns", status, 0 );
ASSERT( c );
ASSERT_EQUALS( c->to , "shard1" );
@@ -128,22 +157,28 @@ namespace mongo {
TEST( BalancerPolicyTests , BalanceEndedDrainingTest ) {
// 2 chunks and 0 chunk (drain completed) shards
- ShardToChunksMap chunkMap;
- vector<BSONObj> chunks;
- chunks.push_back(BSON(ChunkType::min(BSON("x" << BSON("$minKey"<<1))) <<
- ChunkType::max(BSON("x" << 49))));
- chunks.push_back(BSON(ChunkType::min(BSON("x" << 49))<<
- ChunkType::max(BSON("x" << BSON("$maxkey"<<1)))));
- chunkMap["shard0"] = chunks;
- chunks.clear();
- chunkMap["shard1"] = chunks;
+ OwnedShardToChunksMap chunkMap;
+ auto_ptr<OwnedPointerVector<ChunkType> > chunks(new OwnedPointerVector<ChunkType>());
+
+ auto_ptr<ChunkType> chunk(new ChunkType());
+ chunk->setMin(BSON("x" << BSON("$minKey" << 1)));
+ chunk->setMax(BSON("x" << 49));
+ chunks->push_back(chunk.release());
+
+ chunk.reset(new ChunkType());
+ chunk->setMin(BSON("x" << 49));
+ chunk->setMax(BSON("x" << BSON("$maxKey" << 1)));
+ chunks->push_back(chunk.release());
+
+ chunkMap.mutableMap()["shard0"] = chunks.release();
+ chunkMap.mutableMap()["shard1"] = new OwnedPointerVector<ChunkType>();
// no limits
ShardInfoMap limitsMap;
limitsMap["shard0"] = ShardInfo( 0, 2, false, false );
limitsMap["shard1"] = ShardInfo( 0, 0, true, false );
- DistributionStatus status( limitsMap, chunkMap );
+ DistributionStatus status(limitsMap, chunkMap.map());
MigrateInfo* c = BalancerPolicy::balance( "ns", status, 0 );
ASSERT( ! c );
}
@@ -151,15 +186,22 @@ namespace mongo {
TEST( BalancerPolicyTests , BalanceImpasseTest ) {
// one maxed out, one draining
// 2 chunks and 0 chunk shards
- ShardToChunksMap chunkMap;
- vector<BSONObj> chunks;
- chunks.push_back(BSON(ChunkType::min(BSON("x" << BSON("$minKey"<<1))) <<
- ChunkType::max(BSON("x" << 49))));
- chunkMap["shard0"] = chunks;
- chunks.clear();
- chunks.push_back(BSON(ChunkType::min(BSON("x" << 49)) <<
- ChunkType::max(BSON("x" << BSON("$maxkey"<<1)))));
- chunkMap["shard1"] = chunks;
+ OwnedShardToChunksMap chunkMap;
+ auto_ptr<OwnedPointerVector<ChunkType> > chunks(new OwnedPointerVector<ChunkType>());
+
+ auto_ptr<ChunkType> chunk(new ChunkType());
+ chunk->setMin(BSON("x" << BSON("$minKey" << 1)));
+ chunk->setMax(BSON("x" << 49));
+ chunks->push_back(chunk.release());
+
+ chunk.reset(new ChunkType());
+ chunk->setMin(BSON("x" << 49));
+ chunk->setMax(BSON("x" << BSON("$maxKey" << 1)));
+ chunks->push_back(chunk.release());
+
+ chunkMap.mutableMap()["shard0"] = new OwnedPointerVector<ChunkType>();
+ chunkMap.mutableMap()["shard1"] = chunks.release();
+ chunkMap.mutableMap()["shard2"] = new OwnedPointerVector<ChunkType>();
// shard0 is draining, shard1 is maxed out, shard2 has writebacks pending
ShardInfoMap limitsMap;
@@ -167,46 +209,52 @@ namespace mongo {
limitsMap["shard1"] = ShardInfo( 1, 1, false, false );
limitsMap["shard2"] = ShardInfo( 0, 1, true, false );
- DistributionStatus status(limitsMap, chunkMap);
+ DistributionStatus status(limitsMap, chunkMap.map());
MigrateInfo* c = BalancerPolicy::balance( "ns", status, 0 );
ASSERT( ! c );
}
- void addShard( ShardToChunksMap& map, unsigned numChunks, bool last ) {
+ void addShard( OwnedShardToChunksMap& map, unsigned numChunks, bool last ) {
unsigned total = 0;
- for ( ShardToChunksMap::const_iterator i = map.begin(); i != map.end(); ++i )
- total += i->second.size();
+ const OwnedShardToChunksMap::MapType& shardToChunks = map.map();
+ for (OwnedShardToChunksMap::MapType::const_iterator i = shardToChunks.begin();
+ i != shardToChunks.end(); ++i) {
+ total += i->second->size();
+ }
stringstream ss;
- ss << "shard" << map.size();
+ ss << "shard" << shardToChunks.size();
string myName = ss.str();
- vector<BSONObj>& chunks = map[myName];
+ auto_ptr<OwnedPointerVector<ChunkType> > chunksList(
+ new OwnedPointerVector<ChunkType>());
for ( unsigned i=0; i<numChunks; i++ ) {
- BSONObj min,max;
+ auto_ptr<ChunkType> chunk(new ChunkType());
if ( i == 0 && total == 0 )
- min = BSON( "x" << BSON( "$minKey" << 1 ) );
+ chunk->setMin(BSON("x" << BSON("$minKey" << 1)));
else
- min = BSON( "x" << total + i );
+ chunk->setMin(BSON("x" << total + i));
if ( last && i == ( numChunks - 1 ) )
- max = BSON( "x" << BSON( "$maxKey" << 1 ) );
+ chunk->setMax(BSON("x" << BSON("$maxKey" << 1)));
else
- max = BSON( "x" << 1 + total + i );
+ chunk->setMax(BSON("x" << 1 + total + i));
- chunks.push_back( BSON(ChunkType::min(min) << ChunkType::max(max)));
+ chunksList->push_back(chunk.release());
}
+ OwnedShardToChunksMap::MapType& mutableShardToChunks = map.mutableMap();
+ mutableShardToChunks[myName] = chunksList.release();
}
- void moveChunk( ShardToChunksMap& map, MigrateInfo* m ) {
- vector<BSONObj>& chunks = map[m->from];
- for ( vector<BSONObj>::iterator i = chunks.begin(); i != chunks.end(); ++i ) {
- if (i->getField(ChunkType::min()).Obj() == m->chunk.min) {
- map[m->to].push_back( *i );
- chunks.erase( i );
+ void moveChunk( OwnedShardToChunksMap& map, MigrateInfo* m ) {
+ vector<ChunkType*>& chunks = map.mutableMap()[m->from]->mutableVector();
+ for (vector<ChunkType*>::iterator i = chunks.begin(); i != chunks.end(); ++i) {
+ if ((*i)->getMin() == m->chunk.min) {
+ map.mutableMap()[m->to]->push_back(*i);
+ chunks.erase(i);
return;
}
}
@@ -214,7 +262,7 @@ namespace mongo {
}
TEST( BalancerPolicyTests, MultipleDraining ) {
- ShardToChunksMap chunks;
+ OwnedShardToChunksMap chunks;
addShard( chunks, 5 , false );
addShard( chunks, 10 , false );
addShard( chunks, 5 , true );
@@ -224,7 +272,7 @@ namespace mongo {
shards["shard1"] = ShardInfo( 0, 5, true, false );
shards["shard2"] = ShardInfo( 0, 5, false, false );
- DistributionStatus d( shards, chunks );
+ DistributionStatus d(shards, chunks.map());
MigrateInfo* m = BalancerPolicy::balance( "ns", d, 0 );
ASSERT( m );
ASSERT_EQUALS( "shard2" , m->to );
@@ -233,7 +281,7 @@ namespace mongo {
TEST( BalancerPolicyTests, TagsDraining ) {
- ShardToChunksMap chunks;
+ OwnedShardToChunksMap chunks;
addShard( chunks, 5 , false );
addShard( chunks, 5 , false );
addShard( chunks, 5 , true );
@@ -249,7 +297,7 @@ namespace mongo {
shards["shard2"].addTag( "b" );
while ( true ) {
- DistributionStatus d( shards, chunks );
+ DistributionStatus d(shards, chunks.map());
d.addTagRange( TagRange( BSON( "x" << -1 ), BSON( "x" << 7 ) , "a" ) );
d.addTagRange( TagRange( BSON( "x" << 7 ), BSON( "x" << 1000 ) , "b" ) );
@@ -265,14 +313,14 @@ namespace mongo {
moveChunk( chunks, m );
}
- ASSERT_EQUALS( 7U , chunks["shard0"].size() );
- ASSERT_EQUALS( 0U , chunks["shard1"].size() );
- ASSERT_EQUALS( 8U , chunks["shard2"].size() );
+ ASSERT_EQUALS( 7U , chunks.mutableMap()["shard0"]->size() );
+ ASSERT_EQUALS( 0U , chunks.mutableMap()["shard1"]->size() );
+ ASSERT_EQUALS( 8U , chunks.mutableMap()["shard2"]->size() );
}
TEST( BalancerPolicyTests, TagsPolicyChange ) {
- ShardToChunksMap chunks;
+ OwnedShardToChunksMap chunks;
addShard( chunks, 5 , false );
addShard( chunks, 5 , false );
addShard( chunks, 5 , true );
@@ -287,7 +335,7 @@ namespace mongo {
while ( true ) {
- DistributionStatus d( shards, chunks );
+ DistributionStatus d(shards, chunks.map());
d.addTagRange( TagRange( BSON( "x" << -1 ), BSON( "x" << 1000 ) , "a" ) );
MigrateInfo* m = BalancerPolicy::balance( "ns", d, 0 );
@@ -297,17 +345,19 @@ namespace mongo {
moveChunk( chunks, m );
}
- ASSERT_EQUALS( 15U , chunks["shard0"].size() + chunks["shard1"].size() );
- ASSERT( chunks["shard0"].size() == 7U || chunks["shard0"].size() == 8U );
- ASSERT_EQUALS( 0U , chunks["shard2"].size() );
+ const size_t shard0Size = chunks.mutableMap()["shard0"]->size();
+ const size_t shard1Size = chunks.mutableMap()["shard1"]->size();
+ ASSERT_EQUALS( 15U , shard0Size + shard1Size );
+ ASSERT(shard0Size == 7U || shard0Size == 8U);
+ ASSERT_EQUALS(0U, chunks.mutableMap()["shard2"]->size());
}
TEST( BalancerPolicyTests, TagsSelector ) {
- ShardToChunksMap chunks;
+ OwnedShardToChunksMap chunks;
ShardInfoMap shards;
- DistributionStatus d( shards, chunks );
+ DistributionStatus d(shards, chunks.map());
ASSERT( d.addTagRange( TagRange( BSON( "x" << 1 ), BSON( "x" << 10 ) , "a" ) ) );
ASSERT( d.addTagRange( TagRange( BSON( "x" << 10 ), BSON( "x" << 20 ) , "b" ) ) );
ASSERT( d.addTagRange( TagRange( BSON( "x" << 20 ), BSON( "x" << 30 ) , "c" ) ) );
@@ -316,13 +366,27 @@ namespace mongo {
ASSERT( ! d.addTagRange( TagRange( BSON( "x" << 22 ), BSON( "x" << 28 ) , "c" ) ) );
ASSERT( ! d.addTagRange( TagRange( BSON( "x" << 28 ), BSON( "x" << 33 ) , "c" ) ) );
- ASSERT_EQUALS("", d.getTagForChunk(BSON(ChunkType::min(BSON("x" << -4)))));
- ASSERT_EQUALS("", d.getTagForChunk(BSON(ChunkType::min(BSON("x" << 0)))));
- ASSERT_EQUALS("a", d.getTagForChunk(BSON(ChunkType::min(BSON("x" << 1)))));
- ASSERT_EQUALS("b", d.getTagForChunk(BSON(ChunkType::min(BSON("x" << 10)))));
- ASSERT_EQUALS("b", d.getTagForChunk(BSON(ChunkType::min(BSON("x" << 15)))));
- ASSERT_EQUALS("c", d.getTagForChunk(BSON(ChunkType::min(BSON("x" << 25)))));
- ASSERT_EQUALS("", d.getTagForChunk(BSON(ChunkType::min(BSON("x" << 35)))));
+ ChunkType chunk;
+ chunk.setMin(BSON("x" << -4));
+ ASSERT_EQUALS("", d.getTagForChunk(chunk));
+
+ chunk.setMin(BSON("x" << 0));
+ ASSERT_EQUALS("", d.getTagForChunk(chunk));
+
+ chunk.setMin(BSON("x" << 1));
+ ASSERT_EQUALS("a", d.getTagForChunk(chunk));
+
+ chunk.setMin(BSON("x" << 10));
+ ASSERT_EQUALS("b", d.getTagForChunk(chunk));
+
+ chunk.setMin(BSON("x" << 15));
+ ASSERT_EQUALS("b", d.getTagForChunk(chunk));
+
+ chunk.setMin(BSON("x" << 25));
+ ASSERT_EQUALS("c", d.getTagForChunk(chunk));
+
+ chunk.setMin(BSON("x" << 35));
+ ASSERT_EQUALS("", d.getTagForChunk(chunk));
}
/**
@@ -332,7 +396,7 @@ namespace mongo {
*/
TEST( BalancerPolicyTests, MaxSizeRespect ) {
- ShardToChunksMap chunks;
+ OwnedShardToChunksMap chunks;
addShard( chunks, 3 , false );
addShard( chunks, 4 , false );
addShard( chunks, 6 , true );
@@ -346,7 +410,7 @@ namespace mongo {
shards["shard1"] = ShardInfo( 0, 4, false, false );
shards["shard2"] = ShardInfo( 0, 6, false, false );
- DistributionStatus d( shards, chunks );
+ DistributionStatus d(shards, chunks.map());
MigrateInfo* m = BalancerPolicy::balance( "ns", d, 0 );
ASSERT( m );
ASSERT_EQUALS( "shard2" , m->from );
@@ -360,7 +424,7 @@ namespace mongo {
*/
TEST( BalancerPolicyTests, MaxSizeNoDrain ) {
- ShardToChunksMap chunks;
+ OwnedShardToChunksMap chunks;
// Shard0 will be overloaded
addShard( chunks, 4 , false );
addShard( chunks, 4 , false );
@@ -375,7 +439,7 @@ namespace mongo {
shards["shard1"] = ShardInfo( 0, 4, false, false );
shards["shard2"] = ShardInfo( 0, 4, false, false );
- DistributionStatus d( shards, chunks );
+ DistributionStatus d(shards, chunks.map());
MigrateInfo* m = BalancerPolicy::balance( "ns", d, 0 );
ASSERT( !m );
}
@@ -410,7 +474,7 @@ namespace mongo {
int numShards = 7;
int numChunks = 0;
- ShardToChunksMap chunks;
+ OwnedShardToChunksMap chunks;
ShardInfoMap shards;
map<string,int> expected;
@@ -442,7 +506,7 @@ namespace mongo {
for (int i = 0; i < numChunks; i++) {
- DistributionStatus d( shards, chunks );
+ DistributionStatus d(shards, chunks.map());
MigrateInfo* m = BalancerPolicy::balance( "ns", d, i != 0 );
if (!m) {