diff options
author | Randolph Tan <randolph@10gen.com> | 2014-07-28 11:35:11 -0400 |
---|---|---|
committer | Randolph Tan <randolph@10gen.com> | 2014-08-07 19:52:15 -0400 |
commit | c30b981260e26dfeff315b766e2887d4f7404f89 (patch) | |
tree | 1920a24df0347024ee79cabd50b035ef82bd8709 /src/mongo/s/balancer_policy_tests.cpp | |
parent | 88cc54431e112cd2edaa9042b3b20ba1b10fce82 (diff) | |
download | mongo-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.cpp | 272 |
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) { |