1

A MongoDB 3.6.3 database has two shards and a mongodump file with partial data of one collection needs to be restored. The first shard is named "fast" while second "slow". The idea is to restore the dump to the "slow" shard. According to sharding rules the data should go to the "slow" shard, but it actually goes to the wrong one when restore is tried.

Before restoring the data, I want to manually move a range of chunks from fast to slow shard, but are unable to properly issue the command. All examples found are showing of moving only one exact chunk. _id is used as a sharding key.

Try 1:

use admin
db.runCommand({ moveChunk: "db.use", bounds : [ {_id : ObjectId("58b60e73e5d4e7019aa2be17")}, {_id : ObjectId("58bca60f5067031c77b03807")} ], to: "rs1" })

This is the response:

{
        "ok" : 0,
        "errmsg" : "no chunk found with the shard key bounds [{ _id: ObjectId('58b60e73e5d4e7019aa2be17') }, { _id: ObjectId('58bca60f5067031c77b03807') })",
        "$clusterTime" : {
                "clusterTime" : Timestamp(1523459407, 14673),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1523459407, 14673)
}

Try 2:

sh.moveChunk("db.use", {_id:{$gt: ObjectId("58b60e73e5d4e7019aa2be17"), $lt: ObjectId("58bca60f5067031c77b03807") }},"rs1")

Response:

{
        "ok" : 0,
        "errmsg" : "no shard key found in chunk query { _id: { $gt: ObjectId('58b60e73e5d4e7019aa2be17'), $lt: ObjectId('58bca60f5067031c77b03807') } }",
        "$clusterTime" : {
                "clusterTime" : Timestamp(1523460271, 11742),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1523460271, 11742)
}

Any idea how to move chunks that belong to certain shard key range?

  • 1
    Are you restoring via the mongos? How many mongos do you have and how are you confirming that data is going to the incorrect shard? It sounds like you are using zone sharding but may not have the ranges set up correctly yet - in most circumstances you should not be manually moving chunks. The problem with your syntax is that the moveChunk command is for a single chunk: the bounds array parameter should match a single chunk and is intended for use with a hashed shard key. You should be using an equality match with find: <query>, instead. – Stennie Apr 11 '18 at 20:11
  • 1
    Note: I'm assuming you have sharded on _id (non-hashed default ObjectID) value to intentionally create a hot shard (aka your "fast" shard) and are trying to use zone sharding to distribute older data across slow shards. This won't be a great approach for scaling if you want to distribute inserts to multiple fast shards in future. With a monotonically increasing shard key like an ObjectID, all inserts will target the single shard that currently has the largest shard key value. – Stennie Apr 11 '18 at 20:19
  • Yes, the restoring is done via mongos. I have three mongos, but have the restore made from only one. I can confirm the data went to wrong shard, as I connected to that shard directly (without mongos) and made the query and saw the records. Zone ranges are set correctly. The issue I have is that moving chunks is taking to much time (estimated to 40+ days). I tried the method written in the answer below and it worked properly. – ssasa Apr 12 '18 at 12:27
  • Shard key is _id a monotonically increasing value. And yes that might not scale properly in the long run. The basic assumption is that the server inserts can scale 10 or 100 more (there are enough CPU and IO resources) if the "fast" dataset and idexes are enough small to fit server memory. – ssasa Apr 12 '18 at 12:31
0

Until a more decent way is found, I used this script solution:

use config
sh.stopBalancer()
var lower=ObjectId("58B60F00e4b03547ad945a8a");
var upper=ObjectId("58BCA680e4b03547ad945a8a");
var query={shard: "rs0", ns: "db.use", "max._id":{$gte: lower}, "min._id": {$lte: upper}};
var cursor=db.chunks.find(query);

cursor.forEach(function(d) {
 print( "chunk: " + d.min._id ); 
 sh.moveChunk("feedback.usage", { "_id" : d.min._id }, "rs1");
});
sh.setBalancerState(true)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.