summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRandolph Tan <randolph@10gen.com>2014-02-14 15:44:56 -0500
committerRandolph Tan <randolph@10gen.com>2014-02-18 16:20:48 -0500
commit3a08be3bf2a1a650c97543a448a8ea0c143a89b6 (patch)
tree8a0d009b84746717cc274617c4df99f450800c6a /src
parenta7a21700a959498aae1383a50bc2a1a76f5d235f (diff)
downloadmongo-3a08be3bf2a1a650c97543a448a8ea0c143a89b6.tar.gz
SERVER-12515 Unable to move hashed shard key chunks created by numInitialChunks
Diffstat (limited to 'src')
-rw-r--r--src/mongo/s/collection_metadata.cpp5
-rw-r--r--src/mongo/s/collection_metadata.h4
-rw-r--r--src/mongo/s/collection_metadata_test.cpp90
3 files changed, 96 insertions, 3 deletions
diff --git a/src/mongo/s/collection_metadata.cpp b/src/mongo/s/collection_metadata.cpp
index f49bc911c40..e3e42e84a2b 100644
--- a/src/mongo/s/collection_metadata.cpp
+++ b/src/mongo/s/collection_metadata.cpp
@@ -337,8 +337,9 @@ namespace mongo {
for ( vector<BSONObj>::const_iterator it = splitKeys.begin(); it != splitKeys.end();
++it ) {
BSONObj split = *it;
- metadata->_chunksMap[chunk.getMin()] = split.getOwned();
- metadata->_chunksMap.insert( make_pair( split.getOwned(), chunk.getMax().getOwned() ) );
+ dassert(split.woCompare(startKey) > 0);
+ metadata->_chunksMap[startKey] = split.getOwned();
+ metadata->_chunksMap.insert( make_pair( split.getOwned(), chunk.getMax().getOwned() ));
metadata->_shardVersion.incMinor();
startKey = split;
}
diff --git a/src/mongo/s/collection_metadata.h b/src/mongo/s/collection_metadata.h
index 8f4588b789b..9916e41c185 100644
--- a/src/mongo/s/collection_metadata.h
+++ b/src/mongo/s/collection_metadata.h
@@ -102,12 +102,14 @@ namespace mongo {
/**
* Returns a new metadata's instance by splitting an existing 'chunk' at the points
- * describe by 'splitKeys'. The first resulting chunk will have 'newShardVersion' and
+ * described by 'splitKeys'. The first resulting chunk will have 'newShardVersion' and
* subsequent one would have that with the minor version incremented at each chunk. The
* caller owns the metadata.
*
* If a new metadata can't be created, returns NULL and fills in 'errMsg', if it was
* provided.
+ *
+ * Note: 'splitKeys' must be sorted in ascending order.
*/
CollectionMetadata* cloneSplit( const ChunkType& chunk,
const vector<BSONObj>& splitKeys,
diff --git a/src/mongo/s/collection_metadata_test.cpp b/src/mongo/s/collection_metadata_test.cpp
index 10fd97a8f5e..b2cdd74aa99 100644
--- a/src/mongo/s/collection_metadata_test.cpp
+++ b/src/mongo/s/collection_metadata_test.cpp
@@ -651,6 +651,96 @@ namespace {
ASSERT( !cloned->keyIsPending(BSON( "a" << 35 )) );
}
+ TEST_F(SingleChunkFixture, SingleSplit) {
+ string errMsg;
+ ChunkType chunk;
+ scoped_ptr<CollectionMetadata> cloned;
+
+ chunk.setMin( BSON("a" << 10) );
+ chunk.setMax( BSON("a" << 20) );
+
+ vector<BSONObj> splitPoints;
+ splitPoints.push_back( BSON("a" << 14) );
+
+ ChunkVersion version;
+ getCollMetadata().getCollVersion().cloneTo( &version );
+ version.incMinor();
+
+ cloned.reset( getCollMetadata().cloneSplit( chunk,
+ splitPoints,
+ version,
+ &errMsg ) );
+
+ ASSERT_EQUALS( errMsg, "" );
+ ASSERT( cloned != NULL );
+
+ ChunkVersion newVersion( cloned->getCollVersion() );
+ ASSERT_EQUALS( version.epoch(), newVersion.epoch() );
+ ASSERT_EQUALS( version.majorVersion(), newVersion.majorVersion() );
+ ASSERT_EQUALS( version.minorVersion() + 1, newVersion.minorVersion() );
+
+ chunk.clear();
+ ASSERT( cloned->getNextChunk(BSON("a" << MINKEY), &chunk) );
+ ASSERT( chunk.getMin().woCompare( BSON("a" << 10) ) == 0 );
+ ASSERT( chunk.getMax().woCompare( BSON("a" << 14) ) == 0 );
+
+ chunk.clear();
+ ASSERT( cloned->getNextChunk(BSON("a" << 14), &chunk) );
+ ASSERT( chunk.getMin().woCompare( BSON("a" << 14) ) == 0 );
+ ASSERT( chunk.getMax().woCompare( BSON("a" << 20) ) == 0 );
+
+ chunk.clear();
+ ASSERT_FALSE( cloned->getNextChunk(BSON("a" << 20), &chunk) );
+ }
+
+ TEST_F(SingleChunkFixture, MultiSplit) {
+ string errMsg;
+ ChunkType chunk;
+ scoped_ptr<CollectionMetadata> cloned;
+
+ chunk.setMin( BSON("a" << 10) );
+ chunk.setMax( BSON("a" << 20) );
+
+ vector<BSONObj> splitPoints;
+ splitPoints.push_back( BSON("a" << 14) );
+ splitPoints.push_back( BSON("a" << 16) );
+
+ ChunkVersion version;
+ getCollMetadata().getCollVersion().cloneTo( &version );
+ version.incMinor();
+
+ cloned.reset( getCollMetadata().cloneSplit( chunk,
+ splitPoints,
+ version,
+ &errMsg ) );
+
+ ASSERT_EQUALS( errMsg, "" );
+ ASSERT( cloned != NULL );
+
+ ChunkVersion newVersion( cloned->getCollVersion() );
+ ASSERT_EQUALS( version.epoch(), newVersion.epoch() );
+ ASSERT_EQUALS( version.majorVersion(), newVersion.majorVersion() );
+ ASSERT_EQUALS( version.minorVersion() + 2, newVersion.minorVersion() );
+
+ chunk.clear();
+ ASSERT( cloned->getNextChunk(BSON("a" << MINKEY), &chunk) );
+ ASSERT( chunk.getMin().woCompare( BSON("a" << 10) ) == 0 );
+ ASSERT( chunk.getMax().woCompare( BSON("a" << 14) ) == 0 );
+
+ chunk.clear();
+ ASSERT( cloned->getNextChunk(BSON("a" << 14), &chunk) );
+ ASSERT( chunk.getMin().woCompare( BSON("a" << 14) ) == 0 );
+ ASSERT( chunk.getMax().woCompare( BSON("a" << 16) ) == 0 );
+
+ chunk.clear();
+ ASSERT( cloned->getNextChunk(BSON("a" << 16), &chunk) );
+ ASSERT( chunk.getMin().woCompare( BSON("a" << 16) ) == 0 );
+ ASSERT( chunk.getMax().woCompare( BSON("a" << 20) ) == 0 );
+
+ chunk.clear();
+ ASSERT_FALSE( cloned->getNextChunk(BSON("a" << 20), &chunk) );
+ }
+
TEST_F(SingleChunkFixture, SplitChunkWithPending) {
string errMsg;