To remove a shard you must ensure the shard's data is migrated to the remaining shards in the cluster. This procedure describes how to safely migrate data and remove a shard.
About this Task
Creating, sharding, or moving collections while performing this procedure may cause interruptions and lead to unexpected results.
Do not use this procedure to migrate an entire cluster to new hardware. To migrate, see Migrate a Self-Managed Sharded Cluster to Different Hardware.
When you remove a shard in a cluster with an uneven chunk distribution, the balancer first removes the chunks from the draining shard and then balances the remaining uneven chunk distribution.
Removing a shard may cause an open change stream cursor to close, and the closed change stream cursor may not be fully resumable.
You can safely restart a cluster during a shard removal process. If you restart a cluster during an ongoing draining process, draining continues automatically after the cluster components restart. MongoDB records the shard draining status in the
config.shardscollection.
Before you Begin
This procedure uses the
sh.moveCollection()method to move collections off of the removed shard. Before you begin this procedure, review themoveCollectionconsiderations and requirements to understand the command behavior.To remove a shard, first connect to one of the cluster's
mongosinstances usingmongosh.
Note
When removing multiple shards, remove them simultaneously rather than one at a time. Removing one shard at a time causes the balancer to drain data into other remaining shards. A shard can only participate in one chunk migration at a time, so removing one shard limits the throughput of data migration.
Steps
Ensure the balancer is enabled
To migrate data from a shard, the balancer process must
be enabled. To check the balancer state, use the
sh.getBalancerState() method:
sh.getBalancerState()
If the operation returns true, the balancer is enabled.
If the operation returns false, see
Enable the Balancer.
Determine the name of the shard to remove
To find the name of the shard, run the listShards command:
db.adminCommand( { listShards: 1 } )
The shards._id field contains the shard name.
Migrate sharded collection data with the balancer
Run the removeShard command for the shard you want to
remove:
db.adminCommand( { removeShard: "<shardName>" } )
Note
mongos converts the
write concern of the
removeShard command to "majority".
The removeShard operation returns:
{ "msg" : "draining started successfully", "state" : "started", "shard" : "<shardName>", "note" : "you need to call moveCollection for collectionsToMove and afterwards movePrimary for the dbsToMove", "dbsToMove" : [ "db1", "db2" ], collectionsToMove: ["db1.collA"] "ok" : 1, "operationTime" : Timestamp(1575398919, 2), "$clusterTime" : { "clusterTime" : Timestamp(1575398919, 2), "signature" : { "hash" : BinData(0,"Oi68poWCFCA7b9kyhIcg+TzaGiA="), "keyId" : Long("6766255701040824328") } } }
The shard enters the draining state and the balancer begins
migrating chunks from the removed shard to other shards in the
cluster. These migrations happens slowly to avoid severe impact on
the overall cluster. Depending on your network capacity and the
amount of data, this operation can take from a few minutes to
several days to complete.
Tip
While the shard is in the draining state, you can use the
reshardCollection command to redistribute
data off of the removed shard.
Moving data with reshardCollection can be faster than
waiting for the balancer to migrate chunks. The cluster ensures
that data is not placed on any draining shards. You can't run
moveCollection and reshardCollection operations
simultaneously.
For the full procedure, see Resharding for Adding and Removing Shards.
Move unsharded collections to another shard
Determine what collections need to be moved
To list the unsharded collections on the shard, use the aggregation stage
$listClusterCatalog:use admin db.aggregate([ { $listClusterCatalog: { shards: true } }, { $match: { $and: [ { sharded: false }, { shards: '<shard_to_remove>' }, { type: { $nin: ["timeseries","view"] } }, { ns: { $not: { $regex: "^enxcol_\..*(\.esc|\.ecc|\.ecoc|\.ecoc\.compact)$" }}}, { $or: [{ns: {$not: { $regex: "\.system\." }}}, {ns: {$regex: "\.system\.buckets\."}}]}, { db: { $ne: 'config' } }, { db: { $ne: 'admin' } } ]}}, { $project: { _id: 0, ns: { $cond: [ "$options.timeseries", { $replaceAll: { input: "$ns", find: ".system.buckets", replacement: "" } }, "$ns" ] } }} ]) Move the collections one by one
To move the collection, run
sh.moveCollection():sh.moveCollection( "<database>.<collection>", "<ID of recipient shard>" ) Note
moveCollectionfails if you run the command on a namespace that is sharded. If you receive this error message, ignore it and return to step1for the next collection.Return to step
1to check that there are no remaining unsharded collections on the draining shard.
Change primary shard
Run the db.printShardingStatus() method:
db.printShardingStatus()
In the databases section of the command output, check the
database.primary field. If the primary field is the
removed shard, you must move that database's primary to a
different shard.
To change a database's primary shard, run the movePrimary
command.
Warning
When you run movePrimary, any collections that were not
moved in the Move unsharded collections to another shard
step are unavailable during the movePrimary process.
db.adminCommand( { movePrimary: <dbName>, to: <shardName> } )
Check migration status
To check the progress of the migration, run
removeShard from the admin database again:
db.adminCommand( { removeShard: "<shardName>" } )
In the output, the remaining field includes these fields:
Field | Description |
|---|---|
| Number of chunks currently remaining on the shard |
| Number of databases whose primary shard is the shard. These databases are specified in
the |
| Of the total number of If After the |
Continue checking the status of the removeShard command until the
number of chunks remaining is 0.
db.adminCommand( { removeShard: "<shardName>" } )
Finalize shard removal
To finalize the shard removal process, re-run the removeShard
command:
db.adminCommand( { removeShard: <shardName> } )
Note
DDL Operations
If you remove a shard while your cluster executes a DDL
operation (an operation that modifies a collection such as
reshardCollection), the removeShard operation
runs after the concurrent DDL operation finishes.
If the shard is removed, the command output resembles the following:
{ msg: 'removeshard completed successfully', state: 'completed', shard: '<shardName>', ok: 1, '$clusterTime': { clusterTime: Timestamp({ t: 1721941519, i: 7 }), signature: { hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0), keyId: Long('0') } }, operationTime: Timestamp({ t: 1721941519, i: 7 }) }