Skip to content

Commit

Permalink
SERVER-2001 don't trigger 'split-at-top' heuristic with special shard…
Browse files Browse the repository at this point in the history
… keys
  • Loading branch information
matulef committed Oct 4, 2012
1 parent eae26e6 commit 0d57a0e
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 16 deletions.
35 changes: 20 additions & 15 deletions src/mongo/s/chunk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,22 +224,27 @@ namespace mongo {
splitPoint.push_back( medianKey );
}

// We assume that if the chunk being split is the first (or last) one on the collection, this chunk is
// likely to see more insertions. Instead of splitting mid-chunk, we use the very first (or last) key
// as a split point.
if ( minIsInf() ) {
splitPoint.clear();
BSONObj key = _getExtremeKey( 1 );
if ( ! key.isEmpty() ) {
splitPoint.push_back( key );
// We assume that if the chunk being split is the first (or last) one on the collection,
// this chunk is likely to see more insertions. Instead of splitting mid-chunk, we use
// the very first (or last) key as a split point.
// This heuristic is skipped for "special" shard key patterns that are not likely to
// produce monotonically increasing or decreasing values (e.g. hashed shard keys).
// TODO: need better way to detect when shard keys vals are increasing/decreasing, and
// use that better method to determine whether to apply heuristic here.
if ( ! skey().isSpecial() ){
if ( minIsInf() ) {
splitPoint.clear();
BSONObj key = _getExtremeKey( 1 );
if ( ! key.isEmpty() ) {
splitPoint.push_back( key );
}
}

}
else if ( maxIsInf() ) {
splitPoint.clear();
BSONObj key = _getExtremeKey( -1 );
if ( ! key.isEmpty() ) {
splitPoint.push_back( key );
else if ( maxIsInf() ) {
splitPoint.clear();
BSONObj key = _getExtremeKey( -1 );
if ( ! key.isEmpty() ) {
splitPoint.push_back( key );
}
}
}

Expand Down
6 changes: 5 additions & 1 deletion src/mongo/s/chunk.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,11 @@ namespace mongo {

// methods, etc..

/**
/** Returns the highest or lowest existing value in the shard-key space.
* Warning: this assumes that the shard key is not "special"- that is, the shardKeyPattern
* is simply an ordered list of ascending/descending field names. Examples:
* {a : 1, b : -1} is not special. {a : "hashed"} is.
*
* if sort 1, return lowest key
* if sort -1, return highest key
* will return empty object if have none
Expand Down
27 changes: 27 additions & 0 deletions src/mongo/s/shardkey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ namespace mongo {
return pattern.isPrefixOf( otherPattern );
}

bool ShardKeyPattern::isSpecial() const {
BSONForEach(e, pattern) {
int fieldVal = e.numberInt();
if ( fieldVal != 1 && fieldVal != -1 ){
return true;
}
}
return false;
}

string ShardKeyPattern::toString() const {
return pattern.toString();
}
Expand Down Expand Up @@ -169,6 +179,21 @@ namespace mongo {
verify( k.extractKey( fromjson("{a:1,sub:{b:2,c:3}}") ).binaryEqual(x) );
verify( k.extractKey( fromjson("{sub:{b:2,c:3},a:1}") ).binaryEqual(x) );
}

void isSpecialTest() {
ShardKeyPattern k1( BSON( "a" << 1) );
verify( ! k1.isSpecial() );

ShardKeyPattern k2( BSON( "a" << -1 << "b" << 1 ) );
verify( ! k2.isSpecial() );

ShardKeyPattern k3( BSON( "a" << "hashed") );
verify( k3.isSpecial() );

ShardKeyPattern k4( BSON( "a" << 1 << "b" << "hashed") );
verify( k4.isSpecial() );
}

void moveToFrontTest() {
ShardKeyPattern sk (BSON("a" << 1 << "b" << 1));

Expand Down Expand Up @@ -232,6 +257,8 @@ namespace mongo {

verify( k.extractKey( a ) < k.extractKey( b ) );

isSpecialTest();

// add middle multitype tests

moveToFrontTest();
Expand Down
9 changes: 9 additions & 0 deletions src/mongo/s/shardkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@ namespace mongo {
*/
bool isPrefixOf( const BSONObj& otherPattern ) const;

/**
* @return
* true if keyPattern contains any computed values, (e.g. {a : "hashed"})
* false if keyPattern consists of only ascending/descending fields (e.g. {a : 1, b : -1})
* With our current index expression language, "special" shard keys are any keys
* that are not a simple list of field names and 1/-1 values.
*/
bool isSpecial() const;

/**
* @return BSONObj with _id and shardkey at front. May return original object.
*/
Expand Down

0 comments on commit 0d57a0e

Please sign in to comment.