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.shards
collection.
Before you Begin
This procedure uses the
sh.moveCollection()
method to move collections off of the removed shard. Before you begin this procedure, review themoveCollection
considerations and requirements to understand the command behavior.To remove a shard, first connect to one of the cluster's
mongos
instances 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.
Remove chunks from the shard
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 drop or movePrimary these databases", "dbsToMove" : [ "db1", "db2" ], "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.
List sharded collection namespaces
To return a list of sharded collection namespaces, use the $shardedDataDistribution
stage and project the ns
field:
use admin db.aggregate( [ { $shardedDataDistribution: { } }, { $project: { ns: 1 } } ] )
Record the output to reference later in this tutorial.
Move collections off of the shard
For each database in the cluster, excluding admin and config, perform these steps:
List the database collections
List the collections in the database, omitting the following types of collections:
Internal collections that support CSFLE
System collections
Time series collections
Views
use <databaseName> db.getCollectionInfos( { $and: [ { type: { $nin: [ "view", "timeseries" ] } }, { name: { $not: { $regex: "^system\." } } }, { name: { $not: { $regex: "^enxcol_\..*(\.esc|\.ecc|\.ecoc|\.ecoc\.compact)$" } } } ] }, { nameOnly: true } ) Move necessary collections
For each collection returned by
getCollectionInfos()
perform the following steps.Note
Only one
moveCollection
operation can be in progress at a time. Complete all sub-steps before moving on to the next collection.Determine whether the collection needs to be moved.
Run the
$collStats
aggregation stage and project thens
andshard
fields:db.<collName>.aggregate( [ { $collStats: { } }, { $project: { ns: 1, shard: 1 } } ] ) If any of the following criteria are met, skip the collection and return to step
i
for the next collection in the database:The
ns
field is present in the$shardedDataDistribution
output from step 4.The
shard
field is not the shard being removed.
If neither of the preceding criteria are met, continue to step
ii
for the current collection.Move the collection.
To move the collection, run
sh.moveCollection()
on the collection:sh.moveCollection( "<namespace>.<collection>", "<ID of recipient shard>" ) Note
moveCollection
fails if you run the command on a namespace that is sharded. If you receive this error message, ignore it and return to stepi
for the next collection.Return to step
i
for each collection in the database.
Repeat the procedure for other databases
Repeat step 6, Move collections off of the shard (and sub-steps) for each database in the cluster.
Return to step
1
to 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 collections off of the 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 }) }