summaryrefslogtreecommitdiff
path: root/src/mongo/s/chunk.cpp
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2016-05-02 22:25:26 -0400
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2016-05-03 14:55:49 -0400
commit6b87a77ced925398b7485abaf0fa36bafcccc52a (patch)
tree422405627d91bef8df441c0d1548f325df44e738 /src/mongo/s/chunk.cpp
parent67fbb57210c9f22b03aacc777364cf8ed8cef5d2 (diff)
downloadmongo-6b87a77ced925398b7485abaf0fa36bafcccc52a.tar.gz
SERVER-23609 Make top chunk split use the balancer to move chunks
Moves all direct access to balancer structures out of the top chunk split optimization code and changes it to an explicit call to the balancer.
Diffstat (limited to 'src/mongo/s/chunk.cpp')
-rw-r--r--src/mongo/s/chunk.cpp108
1 files changed, 7 insertions, 101 deletions
diff --git a/src/mongo/s/chunk.cpp b/src/mongo/s/chunk.cpp
index 9dc814af604..44ebb40b5b3 100644
--- a/src/mongo/s/chunk.cpp
+++ b/src/mongo/s/chunk.cpp
@@ -34,25 +34,18 @@
#include "mongo/client/connpool.h"
#include "mongo/client/read_preference.h"
-#include "mongo/client/remote_command_targeter.h"
#include "mongo/db/commands.h"
#include "mongo/db/lasterror.h"
-#include "mongo/db/query/query_solution.h"
-#include "mongo/db/write_concern.h"
-#include "mongo/db/write_concern_options.h"
#include "mongo/platform/random.h"
#include "mongo/rpc/get_status_from_command_result.h"
-#include "mongo/s/balance.h"
-#include "mongo/s/balancer_policy.h"
+#include "mongo/s/balancer/balancer.h"
#include "mongo/s/balancer/balancer_configuration.h"
-#include "mongo/s/balancer/cluster_statistics.h"
#include "mongo/s/catalog/catalog_manager.h"
#include "mongo/s/catalog/type_chunk.h"
#include "mongo/s/catalog/type_collection.h"
#include "mongo/s/chunk_manager.h"
#include "mongo/s/client/shard_registry.h"
#include "mongo/s/grid.h"
-#include "mongo/s/migration_secondary_throttle_options.h"
#include "mongo/s/move_chunk_request.h"
#include "mongo/s/shard_util.h"
#include "mongo/util/log.h"
@@ -72,93 +65,6 @@ namespace {
const uint64_t kTooManySplitPoints = 4;
-/**
- * Attempts to move the given chunk to another shard.
- *
- * Returns true if the chunk was actually moved.
- */
-bool tryMoveToOtherShard(OperationContext* txn,
- const ChunkManager* manager,
- const ChunkType& chunk) {
- auto clusterStatsStatus(Balancer::get(txn)->getClusterStatistics()->getStats(txn));
- if (!clusterStatsStatus.isOK()) {
- warning() << "Could not get cluster statistics "
- << causedBy(clusterStatsStatus.getStatus());
- return false;
- }
-
- const auto clusterStats(std::move(clusterStatsStatus.getValue()));
-
- if (clusterStats.size() < 2) {
- LOG(0) << "no need to move top chunk since there's only 1 shard";
- return false;
- }
-
- // Reload sharding metadata before starting migration. Only reload the differences though,
- // because the entire chunk manager was reloaded during the call to split, which immediately
- // precedes this move logic
- shared_ptr<ChunkManager> chunkMgr = manager->reload(txn, false);
-
- map<string, vector<ChunkType>> shardToChunkMap;
- DistributionStatus::populateShardToChunksMap(clusterStats, *chunkMgr, &shardToChunkMap);
-
- StatusWith<string> tagStatus =
- grid.catalogManager(txn)->getTagForChunk(txn, manager->getns(), chunk);
- if (!tagStatus.isOK()) {
- warning() << "Not auto-moving chunk because of an error encountered while "
- << "checking tag for chunk: " << tagStatus.getStatus();
- return false;
- }
-
- DistributionStatus chunkDistribution(clusterStats, shardToChunkMap);
- const string newLocation(chunkDistribution.getBestReceieverShard(tagStatus.getValue()));
-
- if (newLocation.empty()) {
- LOG(1) << "recently split chunk: " << chunk << " but no suitable shard to move to";
- return false;
- }
-
- if (chunk.getShard() == newLocation) {
- // if this is the best shard, then we shouldn't do anything.
- LOG(1) << "recently split chunk: " << chunk << " already in the best shard";
- return false;
- }
-
- shared_ptr<Chunk> toMove = chunkMgr->findIntersectingChunk(txn, chunk.getMin());
-
- if (!(toMove->getMin() == chunk.getMin() && toMove->getMax() == chunk.getMax())) {
- LOG(1) << "recently split chunk: " << chunk << " modified before we could migrate "
- << toMove->toString();
- return false;
- }
-
- log() << "moving chunk (auto): " << toMove->toString() << " to: " << newLocation;
-
- shared_ptr<Shard> newShard = grid.shardRegistry()->getShard(txn, newLocation);
- if (!newShard) {
- warning() << "Newly selected shard " << newLocation << " could not be found.";
- return false;
- }
-
- BSONObj res;
- WriteConcernOptions noThrottle;
- if (!toMove->moveAndCommit(
- txn,
- newShard->getId(),
- Grid::get(txn)->getBalancerConfiguration()->getMaxChunkSizeBytes(),
- MigrationSecondaryThrottleOptions::create(MigrationSecondaryThrottleOptions::kOff),
- false, /* waitForDelete - small chunk, no need */
- 0, /* maxTimeMS - don't time out */
- res)) {
- msgassertedNoTrace(10412, str::stream() << "moveAndCommit failed: " << res);
- }
-
- // update our config
- manager->reload(txn);
-
- return true;
-}
-
} // namespace
Chunk::Chunk(OperationContext* txn, ChunkManager* manager, const ChunkType& from)
@@ -522,18 +428,18 @@ bool Chunk::splitIfShould(OperationContext* txn, long dataWritten) {
// inserts will fall on the top chunk.
if (suggestedMigrateChunk && shouldBalance) {
ChunkType chunkToMove;
- {
- const auto shard = grid.shardRegistry()->getShard(txn, getShardId());
- chunkToMove.setShard(shard->toString());
- }
+ chunkToMove.setNS(_manager->getns());
+ chunkToMove.setShard(getShardId());
chunkToMove.setMin(suggestedMigrateChunk->first);
chunkToMove.setMax(suggestedMigrateChunk->second);
- tryMoveToOtherShard(txn, _manager, chunkToMove);
+ msgassertedNoTraceWithStatus(
+ 10412, Balancer::get(txn)->rebalanceSingleChunk(txn, chunkToMove));
+ _manager->reload(txn);
}
return true;
- } catch (DBException& e) {
+ } catch (const DBException& e) {
// TODO: Make this better - there are lots of reasons a split could fail
// Random so that we don't sync up with other failed splits
_dataWritten = mkDataWritten();