diff options
author | Hugh Han <hughhan1@gmail.com> | 2017-06-23 14:43:32 -0400 |
---|---|---|
committer | Hugh Han <hughhan1@gmail.com> | 2017-07-13 13:45:20 -0400 |
commit | 9e478e41643e736104e15d6bc7a3065c19b37e17 (patch) | |
tree | f3692decf1e09c0915c64551c7587bf51896b340 /src/mongo/db | |
parent | 26a2c5ded2cd5adbd3f18e460dc61f7226a51573 (diff) | |
download | mongo-9e478e41643e736104e15d6bc7a3065c19b37e17.tar.gz |
SERVER-14761 only allow NumberLong as split key in hashed shard patterns
When a shard uses a hashed key pattern, only NumberLong types may be used
as split keys.
A small bug in hash_basic.js regarding 'middle' syntax was also fixed.
Instead of 10000 to the document as a whole, 10000 is now added to the
actual number in the document.
A small bug in read_only_test.js regarding the shardColl(...) function
was also found. It was fixed to now do what I believe the author originally
intended it to do.
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/s/split_chunk_command.cpp | 76 |
1 files changed, 48 insertions, 28 deletions
diff --git a/src/mongo/db/s/split_chunk_command.cpp b/src/mongo/db/s/split_chunk_command.cpp index cfc2c04ad55..cc43284a7ef 100644 --- a/src/mongo/db/s/split_chunk_command.cpp +++ b/src/mongo/db/s/split_chunk_command.cpp @@ -202,22 +202,6 @@ public: const BSONObj min = chunkRange.getMin(); const BSONObj max = chunkRange.getMax(); - vector<BSONObj> splitKeys; - { - BSONElement splitKeysElem; - auto splitKeysElemStatus = - bsonExtractTypedField(cmdObj, "splitKeys", mongo::Array, &splitKeysElem); - - if (!splitKeysElemStatus.isOK()) { - errmsg = "need to provide the split points to chunk over"; - return false; - } - BSONObjIterator it(splitKeysElem.Obj()); - while (it.more()) { - splitKeys.push_back(it.next().Obj().getOwned()); - } - } - string shardName; auto parseShardNameStatus = bsonExtractStringField(cmdObj, "from", &shardName); if (!parseShardNameStatus.isOK()) @@ -265,6 +249,54 @@ public: return false; } + ScopedCollectionMetadata collMetadata; + { + AutoGetCollection autoColl(opCtx, nss, MODE_IS); + + // Get collection metadata + collMetadata = CollectionShardingState::get(opCtx, nss.ns())->getMetadata(); + } + + // With nonzero shard version, we must have metadata + invariant(collMetadata); + + KeyPattern shardKeyPattern(collMetadata->getKeyPattern()); + + vector<BSONObj> splitKeys; + { + BSONElement splitKeysElem; + auto splitKeysElemStatus = + bsonExtractTypedField(cmdObj, "splitKeys", mongo::Array, &splitKeysElem); + + if (!splitKeysElemStatus.isOK()) { + errmsg = "need to provide the split points to chunk over"; + return false; + } + + BSONObjIterator it(splitKeysElem.Obj()); + + // If the shard uses a hashed key, then we must make sure that the split point is of + // type NumberLong. + if (KeyPattern::isHashedKeyPattern(shardKeyPattern.toBSON())) { + while (it.more()) { + BSONObj splitKeyObj = it.next().Obj(); + BSONObjIterator keyIt(splitKeyObj); + while (keyIt.more()) { + BSONElement splitKey = keyIt.next(); + if (splitKey.type() != NumberLong) { + errmsg = "split point must be of type NumberLong"; + return false; + } + } + splitKeys.push_back(splitKeyObj.getOwned()); + } + } else { + while (it.more()) { + splitKeys.push_back(it.next().Obj().getOwned()); + } + } + } + OID expectedCollectionEpoch; if (cmdObj.hasField("epoch")) { auto epochStatus = bsonExtractOIDField(cmdObj, "epoch", &expectedCollectionEpoch); @@ -293,17 +325,6 @@ public: return appendCommandStatus(result, {ErrorCodes::StaleEpoch, msg}); } - ScopedCollectionMetadata collMetadata; - { - AutoGetCollection autoColl(opCtx, nss, MODE_IS); - - // Get collection metadata - collMetadata = CollectionShardingState::get(opCtx, nss.ns())->getMetadata(); - } - - // With nonzero shard version, we must have metadata - invariant(collMetadata); - ChunkVersion collVersion = collMetadata->getCollVersion(); // With nonzero shard version, we must have a coll version >= our shard version invariant(collVersion >= shardVersion); @@ -389,7 +410,6 @@ public: } // Select chunk to move out for "top chunk optimization". - KeyPattern shardKeyPattern(collMetadata->getKeyPattern()); AutoGetCollection autoColl(opCtx, nss, MODE_IS); |