diff options
author | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2017-02-16 17:28:43 -0500 |
---|---|---|
committer | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2017-02-28 16:04:51 -0500 |
commit | 009752a819e0d53317ec517f94d9aabf3061445b (patch) | |
tree | 7930cbfe7a1d0e9a95fad3d9a5adb52aea3fcd7a | |
parent | ad1a3c97ec9cb2b3ece963a8674a05f5d8194c13 (diff) | |
download | mongo-009752a819e0d53317ec517f94d9aabf3061445b.tar.gz |
SERVER-28030 Remove writes from Chunk
(cherry picked from commit 41729cec076164077f13571e35596934477d7110)
-rw-r--r-- | src/mongo/db/s/balancer/balancer.cpp | 18 | ||||
-rw-r--r-- | src/mongo/dbtests/chunktests.cpp | 76 | ||||
-rw-r--r-- | src/mongo/s/chunk.cpp | 46 | ||||
-rw-r--r-- | src/mongo/s/chunk.h | 33 | ||||
-rw-r--r-- | src/mongo/s/chunk_manager.cpp | 16 |
5 files changed, 78 insertions, 111 deletions
diff --git a/src/mongo/db/s/balancer/balancer.cpp b/src/mongo/db/s/balancer/balancer.cpp index 75973319966..75c9d5243cd 100644 --- a/src/mongo/db/s/balancer/balancer.cpp +++ b/src/mongo/db/s/balancer/balancer.cpp @@ -654,7 +654,23 @@ void Balancer::_splitOrMarkJumbo(OperationContext* txn, ChunkRange(chunk->getMin(), chunk->getMax()), splitPoints)); } catch (const DBException& ex) { - chunk->markAsJumbo(txn); + log() << "Marking chunk " << redact(chunk->toString()) << " as jumbo."; + + chunk->markAsJumbo(); + + const std::string chunkName = ChunkType::genID(nss.ns(), chunk->getMin()); + + auto status = Grid::get(txn)->catalogClient(txn)->updateConfigDocument( + txn, + ChunkType::ConfigNS, + BSON(ChunkType::name(chunkName)), + BSON("$set" << BSON(ChunkType::jumbo(true))), + false, + ShardingCatalogClient::kMajorityWriteConcern); + if (!status.isOK()) { + log() << "Couldn't set jumbo for chunk: " << redact(chunkName) + << causedBy(redact(status.getStatus())); + } } } diff --git a/src/mongo/dbtests/chunktests.cpp b/src/mongo/dbtests/chunktests.cpp index 86a95684387..047d765e431 100644 --- a/src/mongo/dbtests/chunktests.cpp +++ b/src/mongo/dbtests/chunktests.cpp @@ -58,13 +58,14 @@ public: const string shardId = str::stream() << (i - 1); _shardIds.insert(shardId); - std::shared_ptr<Chunk> chunk(new Chunk(this, - mySplitPoints[i - 1], - mySplitPoints[i], - shardId, - ChunkVersion(0, 0, OID()), - 0)); - _chunkMap[mySplitPoints[i]] = chunk; + ChunkType chunk; + chunk.setNS(getns()); + chunk.setMin(mySplitPoints[i - 1]); + chunk.setMax(mySplitPoints[i]); + chunk.setShard(shardId); + chunk.setVersion(ChunkVersion(0, 0, OID())); + + _chunkMap[mySplitPoints[i]] = std::make_shared<Chunk>(chunk); } _chunkRangeMap = _constructRanges(_chunkMap); @@ -84,8 +85,9 @@ public: auto opCtx = serviceContext.makeOperationContext(); ShardKeyPattern shardKeyPattern(shardKey()); - TestableChunkManager chunkManager("", shardKeyPattern, defaultCollator(), false); - chunkManager.setSingleChunkForShards(splitPointsVector()); + TestableChunkManager chunkManager( + "TestDB.TestColl", shardKeyPattern, defaultCollator(), false); + chunkManager.setSingleChunkForShards(splitPoints()); set<ShardId> shardIds; chunkManager.getShardIdsForQuery(opCtx.get(), query(), queryCollation(), &shardIds); @@ -106,8 +108,8 @@ protected: return {nullptr}; } - virtual BSONArray splitPoints() const { - return BSONArray(); + virtual std::vector<BSONObj> splitPoints() const { + return {}; } virtual BSONObj query() const { @@ -121,30 +123,21 @@ protected: virtual BSONArray expectedShardNames() const { return BSON_ARRAY("0"); } - - virtual vector<BSONObj> splitPointsVector() const { - vector<BSONObj> ret; - BSONArray a = splitPoints(); - BSONObjIterator i(a); - while (i.more()) { - ret.push_back(i.next().Obj().getOwned()); - } - return ret; - } }; class EmptyQuerySingleShard : public Base {}; class MultiShardBase : public Base { - virtual BSONArray splitPoints() const { - return BSON_ARRAY(BSON("a" - << "x") - << BSON("a" - << "y") - << BSON("a" - << "z")); + virtual std::vector<BSONObj> splitPoints() const { + return {BSON("a" + << "x"), + BSON("a" + << "y"), + BSON("a" + << "z")}; } }; + class EmptyQueryMultiShard : public MultiShardBase { virtual BSONArray expectedShardNames() const { return BSON_ARRAY("0" @@ -172,6 +165,7 @@ class EqualityRangeMultiShard : public MultiShardBase { return BSON("a" << "y"); } + virtual BSONArray expectedShardNames() const { return BSON_ARRAY("2"); } @@ -181,6 +175,7 @@ class SetRangeMultiShard : public MultiShardBase { virtual BSONObj query() const { return fromjson("{a:{$in:['u','y']}}"); } + virtual BSONArray expectedShardNames() const { return BSON_ARRAY("0" << "2"); @@ -191,6 +186,7 @@ class GTRangeMultiShard : public MultiShardBase { virtual BSONObj query() const { return BSON("a" << GT << "x"); } + virtual BSONArray expectedShardNames() const { return BSON_ARRAY("1" << "2" @@ -202,6 +198,7 @@ class GTERangeMultiShard : public MultiShardBase { virtual BSONObj query() const { return BSON("a" << GTE << "x"); } + virtual BSONArray expectedShardNames() const { return BSON_ARRAY("1" << "2" @@ -229,6 +226,7 @@ class LTERangeMultiShard : public MultiShardBase { virtual BSONObj query() const { return BSON("a" << LTE << "y"); } + virtual BSONArray expectedShardNames() const { return BSON_ARRAY("0" << "1" @@ -240,6 +238,7 @@ class OrEqualities : public MultiShardBase { virtual BSONObj query() const { return fromjson("{$or:[{a:'u'},{a:'y'}]}"); } + virtual BSONArray expectedShardNames() const { return BSON_ARRAY("0" << "2"); @@ -250,6 +249,7 @@ class OrEqualityInequality : public MultiShardBase { virtual BSONObj query() const { return fromjson("{$or:[{a:'u'},{a:{$gte:'y'}}]}"); } + virtual BSONArray expectedShardNames() const { return BSON_ARRAY("0" << "2" @@ -297,6 +297,7 @@ class EqualityThenUnsatisfiable : public Unsatisfiable<Base> { virtual BSONObj shardKey() const { return BSON("a" << 1 << "b" << 1); } + virtual BSONObj query() const { return BSON("a" << 1 << "b" << GT << 4 << LT << 4); } @@ -306,6 +307,7 @@ class InequalityThenUnsatisfiable : public Unsatisfiable<Base> { virtual BSONObj shardKey() const { return BSON("a" << 1 << "b" << 1); } + virtual BSONObj query() const { return BSON("a" << GT << 1 << "b" << GT << 4 << LT << 4); } @@ -328,8 +330,8 @@ class CompoundKeyBase : public Base { return BSON("a" << 1 << "b" << 1); } - virtual BSONArray splitPoints() const { - return BSON_ARRAY(BSON("a" << 5 << "b" << 10) << BSON("a" << 5 << "b" << 20)); + virtual std::vector<BSONObj> splitPoints() const { + return {BSON("a" << 5 << "b" << 10), BSON("a" << 5 << "b" << 20)}; } }; @@ -354,10 +356,12 @@ class CollationStringsMultiShard : public MultiShardBase { return BSON("a" << "y"); } + virtual BSONObj queryCollation() const { return BSON("locale" << "mock_reverse_string"); } + virtual BSONArray expectedShardNames() const { return BSON_ARRAY("0" << "1" @@ -371,11 +375,13 @@ class DefaultCollationStringsMultiShard : public MultiShardBase { return BSON("a" << "y"); } + virtual std::unique_ptr<CollatorInterface> defaultCollator() const { auto collator = stdx::make_unique<CollatorInterfaceMock>( CollatorInterfaceMock::MockType::kReverseString); return {std::move(collator)}; } + virtual BSONArray expectedShardNames() const { return BSON_ARRAY("0" << "1" @@ -389,15 +395,18 @@ class SimpleCollationStringsMultiShard : public MultiShardBase { return BSON("a" << "y"); } + virtual std::unique_ptr<CollatorInterface> defaultCollator() const { auto collator = stdx::make_unique<CollatorInterfaceMock>( CollatorInterfaceMock::MockType::kReverseString); return {std::move(collator)}; } + virtual BSONObj queryCollation() const { return BSON("locale" << "simple"); } + virtual BSONArray expectedShardNames() const { return BSON_ARRAY("2"); } @@ -407,10 +416,12 @@ class CollationNumbersMultiShard : public MultiShardBase { virtual BSONObj query() const { return BSON("a" << 5); } + virtual BSONObj queryCollation() const { return BSON("locale" << "mock_reverse_string"); } + virtual BSONArray expectedShardNames() const { return BSON_ARRAY("0"); } @@ -420,11 +431,13 @@ class DefaultCollationNumbersMultiShard : public MultiShardBase { virtual BSONObj query() const { return BSON("a" << 5); } + virtual std::unique_ptr<CollatorInterface> defaultCollator() const { auto collator = stdx::make_unique<CollatorInterfaceMock>( CollatorInterfaceMock::MockType::kReverseString); return {std::move(collator)}; } + virtual BSONArray expectedShardNames() const { return BSON_ARRAY("0"); } @@ -434,15 +447,18 @@ class SimpleCollationNumbersMultiShard : public MultiShardBase { virtual BSONObj query() const { return BSON("a" << 5); } + virtual std::unique_ptr<CollatorInterface> defaultCollator() const { auto collator = stdx::make_unique<CollatorInterfaceMock>( CollatorInterfaceMock::MockType::kReverseString); return {std::move(collator)}; } + virtual BSONObj queryCollation() const { return BSON("locale" << "simple"); } + virtual BSONArray expectedShardNames() const { return BSON_ARRAY("0"); } diff --git a/src/mongo/s/chunk.cpp b/src/mongo/s/chunk.cpp index ff4341c3f7f..3c726477bc1 100644 --- a/src/mongo/s/chunk.cpp +++ b/src/mongo/s/chunk.cpp @@ -34,9 +34,6 @@ #include "mongo/platform/random.h" #include "mongo/s/balancer_configuration.h" -#include "mongo/s/catalog/sharding_catalog_client.h" -#include "mongo/s/catalog/type_chunk.h" -#include "mongo/s/chunk_manager.h" #include "mongo/s/grid.h" #include "mongo/util/log.h" @@ -57,10 +54,8 @@ int64_t mkDataWritten() { } // namespace -Chunk::Chunk(ChunkManager* manager, const ChunkType& from) - : _manager(manager), - _min(from.getMin().getOwned()), - _max(from.getMax().getOwned()), +Chunk::Chunk(const ChunkType& from) + : _range(from.getMin(), from.getMax()), _shardId(from.getShard()), _lastmod(from.getVersion()), _jumbo(from.getJumbo()), @@ -68,20 +63,6 @@ Chunk::Chunk(ChunkManager* manager, const ChunkType& from) invariantOK(from.validate()); } -Chunk::Chunk(ChunkManager* manager, - const BSONObj& min, - const BSONObj& max, - const ShardId& shardId, - ChunkVersion lastmod, - uint64_t initialDataWritten) - : _manager(manager), - _min(min), - _max(max), - _shardId(shardId), - _lastmod(lastmod), - _jumbo(false), - _dataWritten(initialDataWritten) {} - bool Chunk::containsKey(const BSONObj& shardKey) const { return getMin().woCompare(shardKey) <= 0 && shardKey.woCompare(getMax()) < 0; } @@ -106,30 +87,11 @@ void Chunk::randomizeBytesWritten() { std::string Chunk::toString() const { return str::stream() << ChunkType::shard() << ": " << _shardId << ", " << ChunkType::DEPRECATED_lastmod() << ": " << _lastmod.toString() << ", " - << ChunkType::min() << ": " << _min << ", " << ChunkType::max() << ": " - << _max; + << _range.toString(); } -void Chunk::markAsJumbo(OperationContext* txn) const { - log() << "Marking chunk " << toString() << " as jumbo."; - - // set this first - // even if we can't set it in the db - // at least this mongos won't try and keep moving +void Chunk::markAsJumbo() { _jumbo = true; - - const std::string chunkName = ChunkType::genID(_manager->getns(), _min); - - auto status = Grid::get(txn)->catalogClient(txn)->updateConfigDocument( - txn, - ChunkType::ConfigNS, - BSON(ChunkType::name(chunkName)), - BSON("$set" << BSON(ChunkType::jumbo(true))), - false, - ShardingCatalogClient::kMajorityWriteConcern); - if (!status.isOK()) { - warning() << "couldn't set jumbo for chunk: " << chunkName << causedBy(status.getStatus()); - } } } // namespace mongo diff --git a/src/mongo/s/chunk.h b/src/mongo/s/chunk.h index 4c107f0d2c2..484a1d9597c 100644 --- a/src/mongo/s/chunk.h +++ b/src/mongo/s/chunk.h @@ -28,38 +28,27 @@ #pragma once -#include "mongo/base/disallow_copying.h" +#include "mongo/s/catalog/type_chunk.h" #include "mongo/s/chunk_version.h" #include "mongo/s/shard_id.h" namespace mongo { -class ChunkManager; -class ChunkType; -class OperationContext; +class BSONObj; /** * Represents a cache entry for a single Chunk. Owned by a ChunkManager. */ class Chunk { - MONGO_DISALLOW_COPYING(Chunk); - public: - Chunk(ChunkManager* manager, const ChunkType& from); - - Chunk(ChunkManager* manager, - const BSONObj& min, - const BSONObj& max, - const ShardId& shardId, - ChunkVersion lastmod, - uint64_t initialDataWritten); + explicit Chunk(const ChunkType& from); const BSONObj& getMin() const { - return _min; + return _range.getMin(); } const BSONObj& getMax() const { - return _max; + return _range.getMax(); } const ShardId& getShardId() const { @@ -94,18 +83,12 @@ public: void randomizeBytesWritten(); /** - * marks this chunk as a jumbo chunk - * that means the chunk will be inelligble for migrates + * Marks this chunk as jumbo. Only moves from false to true once and is used by the balancer. */ - void markAsJumbo(OperationContext* txn) const; + void markAsJumbo(); private: - // The chunk manager, which owns this chunk. Not owned by the chunk. - const ChunkManager* _manager; - - const BSONObj _min; - - const BSONObj _max; + const ChunkRange _range; const ShardId _shardId; diff --git a/src/mongo/s/chunk_manager.cpp b/src/mongo/s/chunk_manager.cpp index f3a1d126ae1..8c8a03bccbc 100644 --- a/src/mongo/s/chunk_manager.cpp +++ b/src/mongo/s/chunk_manager.cpp @@ -102,7 +102,7 @@ public: pair<BSONObj, shared_ptr<Chunk>> rangeFor(OperationContext* txn, const ChunkType& chunk) const final { - return std::make_pair(chunk.getMax(), std::make_shared<Chunk>(_manager, chunk)); + return std::make_pair(chunk.getMax(), std::make_shared<Chunk>(chunk)); } ShardId shardFor(OperationContext* txn, const ShardId& shardId) const final { @@ -267,19 +267,9 @@ bool ChunkManager::_load(OperationContext* txn, // Load a copy of the chunk map, replacing the chunk manager with our own const ChunkMap& oldChunkMap = oldManager->getChunkMap(); - // Could be v.expensive - // TODO: If chunks were immutable and didn't reference the manager, we could do more - // interesting things here for (const auto& oldChunkMapEntry : oldChunkMap) { - shared_ptr<Chunk> oldC = oldChunkMapEntry.second; - shared_ptr<Chunk> newC(new Chunk(this, - oldC->getMin(), - oldC->getMax(), - oldC->getShardId(), - oldC->getLastmod(), - oldC->getBytesWritten())); - - chunkMap.insert(std::make_pair(oldC->getMax(), newC)); + const auto& oldC = oldChunkMapEntry.second; + chunkMap.emplace(oldC->getMax(), std::make_shared<Chunk>(*oldC)); } LOG(2) << "loading chunk manager for collection " << _ns |