diff options
author | Randolph Tan <randolph@10gen.com> | 2014-02-14 15:44:56 -0500 |
---|---|---|
committer | Randolph Tan <randolph@10gen.com> | 2014-02-18 16:20:48 -0500 |
commit | 3a08be3bf2a1a650c97543a448a8ea0c143a89b6 (patch) | |
tree | 8a0d009b84746717cc274617c4df99f450800c6a /src/mongo/s | |
parent | a7a21700a959498aae1383a50bc2a1a76f5d235f (diff) | |
download | mongo-3a08be3bf2a1a650c97543a448a8ea0c143a89b6.tar.gz |
SERVER-12515 Unable to move hashed shard key chunks created by numInitialChunks
Diffstat (limited to 'src/mongo/s')
-rw-r--r-- | src/mongo/s/collection_metadata.cpp | 5 | ||||
-rw-r--r-- | src/mongo/s/collection_metadata.h | 4 | ||||
-rw-r--r-- | src/mongo/s/collection_metadata_test.cpp | 90 |
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; |