Skip to content
Browse files

test and fix for zero-version being sent to unneeded shards during sc…

…atter/gather
  • Loading branch information...
1 parent 068cad4 commit f93918db8ec15c9de7c884d0a560a185a8ef423d gregs committed
Showing with 66 additions and 24 deletions.
  1. +48 −0 jstests/sharding/no_empty_reset.js
  2. +17 −23 s/chunk.cpp
  3. +1 −1 s/chunk.h
View
48 jstests/sharding/no_empty_reset.js
@@ -0,0 +1,48 @@
+// Tests that an empty shard can't be the cause of a chunk reset
+
+var st = new ShardingTest({ shards : 2, mongos : 2 })
+
+var coll = st.s.getCollection( jsTestName() + ".coll" )
+
+for( var i = -10; i < 10; i++ )
+ coll.insert({ _id : i })
+
+st.shardColl( coll, { _id : 1 }, { _id : 0 } )
+
+jsTestLog( "Sharded setup complete" )
+
+st.printShardingStatus()
+
+jsTestLog( "Setting initial versions for each mongos..." )
+
+coll.find().itcount()
+
+var collB = st.s1.getCollection( "" + coll )
+collB.find().itcount()
+
+jsTestLog( "Migrating via first mongos..." )
+
+var fullShard = st.getShard( coll, { _id : 1 } )
+var emptyShard = st.getShard( coll, { _id : -1 } )
+
+var admin = st.s.getDB( "admin" )
+printjson( admin.runCommand({ moveChunk : "" + coll, find : { _id : -1 }, to : fullShard.shardName }) )
+
+jsTestLog( "Resetting shard version via first mongos..." )
+
+coll.find().itcount()
+
+jsTestLog( "Making sure we don't insert into the wrong shard..." )
+
+collB.insert({ _id : -11 })
+
+var emptyColl = emptyShard.getCollection( "" + coll )
+
+print( emptyColl )
+print( emptyShard )
+print( emptyShard.shardName )
+st.printShardingStatus()
+
+assert.eq( 0, emptyColl.find().itcount() )
+
+
View
40 s/chunk.cpp
@@ -756,33 +756,21 @@ namespace mongo {
FieldRange range = frsp->singleKeyRange(_key.key().firstElementFieldName());
if ( !range.nontrivial() ) {
DEV PRINT(range.nontrivial());
- getAllShards(shards);
+ getShardsForRange( shards, _key.globalMin(), _key.globalMax() );
return;
}
}
BoundList ranges = frsp->singleKeyIndexBounds(_key.key(), 1);
for (BoundList::const_iterator it=ranges.begin(), end=ranges.end(); it != end; ++it) {
+
BSONObj minObj = it->first.replaceFieldNames(_key.key());
BSONObj maxObj = it->second.replaceFieldNames(_key.key());
- ChunkRangeMap::const_iterator min, max;
- min = _chunkRanges.upper_bound(minObj);
- max = _chunkRanges.upper_bound(maxObj);
-
- massert( 13507 , str::stream() << "invalid chunk config minObj: " << minObj , min != _chunkRanges.ranges().end());
-
- // make max non-inclusive like end iterators
- if(max != _chunkRanges.ranges().end())
- ++max;
-
- for (ChunkRangeMap::const_iterator it=min; it != max; ++it) {
- shards.insert(it->second->getShard());
- }
+ getShardsForRange( shards, minObj, maxObj, false );
// once we know we need to visit all shards no need to keep looping
- //if (shards.size() == _shards.size())
- //return;
+ if( shards.size() == _shards.size() ) return;
}
if (org.moreOrClauses())
@@ -792,19 +780,25 @@ namespace mongo {
while (org.moreOrClauses());
}
- void ChunkManager::getShardsForRange(set<Shard>& shards, const BSONObj& min, const BSONObj& max) const {
- uassert(13405, "min must have shard key", hasShardKey(min));
- uassert(13406, "max must have shard key", hasShardKey(max));
+ void ChunkManager::getShardsForRange(set<Shard>& shards, const BSONObj& min, const BSONObj& max, bool fullKeyReq ) const {
+
+ if( fullKeyReq ){
+ uassert(13405, str::stream() << "min value " << min << " does not have shard key", hasShardKey(min));
+ uassert(13406, str::stream() << "max value " << max << " does not have shard key", hasShardKey(max));
+ }
ChunkRangeMap::const_iterator it = _chunkRanges.upper_bound(min);
- ChunkRangeMap::const_iterator end = _chunkRanges.lower_bound(max);
+ ChunkRangeMap::const_iterator end = _chunkRanges.upper_bound(max);
+
+ massert( 13507 , str::stream() << "no chunks found between bounds " << min << " and " << max , it != _chunkRanges.ranges().end() );
+
+ if( end != _chunkRanges.ranges().end() ) ++end;
- for (; it!=end; ++ it) {
+ for( ; it != end; ++it ){
shards.insert(it->second->getShard());
// once we know we need to visit all shards no need to keep looping
- if (shards.size() == _shards.size())
- break;
+ if (shards.size() == _shards.size()) break;
}
}
View
2 s/chunk.h
@@ -317,7 +317,7 @@ namespace mongo {
void getShardsForQuery( set<Shard>& shards , const BSONObj& query ) const;
void getAllShards( set<Shard>& all ) const;
- void getShardsForRange(set<Shard>& shards, const BSONObj& min, const BSONObj& max) const; // [min, max)
+ void getShardsForRange(set<Shard>& shards, const BSONObj& min, const BSONObj& max, bool fullKeyReq = true) const; // [min, max)
string toString() const;

0 comments on commit f93918d

Please sign in to comment.
Something went wrong with that request. Please try again.