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 }) }