Skip to content
Browse files

SERVER-2001 don't trigger 'split-at-top' heuristic with special shard…

… keys
  • Loading branch information...
1 parent eae26e6 commit 0d57a0eb93dc750e15e5c459d15aeb8f14296471 @matulef matulef committed Oct 4, 2012
Showing with 61 additions and 16 deletions.
  1. +20 −15 src/mongo/s/chunk.cpp
  2. +5 −1 src/mongo/s/chunk.h
  3. +27 −0 src/mongo/s/shardkey.cpp
  4. +9 −0 src/mongo/s/shardkey.h
View
35 src/mongo/s/chunk.cpp
@@ -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 );
+ }
}
}
View
6 src/mongo/s/chunk.h
@@ -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
View
27 src/mongo/s/shardkey.cpp
@@ -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();
}
@@ -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));
@@ -232,6 +257,8 @@ namespace mongo {
verify( k.extractKey( a ) < k.extractKey( b ) );
+ isSpecialTest();
+
// add middle multitype tests
moveToFrontTest();
View
9 src/mongo/s/shardkey.h
@@ -86,6 +86,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.
*/
BSONObj moveToFront(const BSONObj& obj) const;

0 comments on commit 0d57a0e

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