summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2017-02-16 17:28:43 -0500
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2017-02-28 16:04:51 -0500
commit009752a819e0d53317ec517f94d9aabf3061445b (patch)
tree7930cbfe7a1d0e9a95fad3d9a5adb52aea3fcd7a
parentad1a3c97ec9cb2b3ece963a8674a05f5d8194c13 (diff)
downloadmongo-009752a819e0d53317ec517f94d9aabf3061445b.tar.gz
SERVER-28030 Remove writes from Chunk
(cherry picked from commit 41729cec076164077f13571e35596934477d7110)
-rw-r--r--src/mongo/db/s/balancer/balancer.cpp18
-rw-r--r--src/mongo/dbtests/chunktests.cpp76
-rw-r--r--src/mongo/s/chunk.cpp46
-rw-r--r--src/mongo/s/chunk.h33
-rw-r--r--src/mongo/s/chunk_manager.cpp16
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