Move a Collection
Starting in MongoDB 8.0, you can move an unsharded collection to a
different shard using the moveCollection
command.
About this Task
moveCollection
can only be run on sharded clusters.moveCollection
can only move unsharded collections.moveCollection
can only move a single collection at a time.moveCollection
has a 5 minute minimum duration.Atlas Search indexes need to be rebuilt after
moveCollection
runs.You cannot make topology changes, such as add or remove shard or transition between embedded and dedicated config servers, until
moveCollection
completes.You cannot run the following operations against the collection that is being moved while
moveCollection
is in progress:You cannot run the following operations against the cluster while
moveCollection
is in progress:Index builds that occur while
moveCollection
is in progress might silently fail.Do not create indexes while
moveCollection
is in progress.Do not call
moveCollection
if there are ongoing index builds.
Access Control
If your deployment has access control enabled,
the enableSharding
role grants you access to run the
moveCollection
command.
Before you Begin
Before you move your collection, ensure that you meet the following requirements:
Your application can tolerate a period of two seconds where the affected collection blocks writes. During the time period where writes are blocked, your application experiences an increase in latency.
Your database meets these resource requirements:
Ensure the shard you are moving the collection to has enough storage space for the collection and its indexes. The destination shard requires at least
( Collection storage size + Index Size ) * 2
bytes available.Ensure that your I/O capacity is below 50%.
Ensure that your CPU load is below 80%.
Important
These requirements are not enforced by the database. A failure to allocate enough resources can result in:
the database running out of space and shutting down
decreased performance
the operation taking longer than expected
If your application has time periods with less traffic, perform this operation on the collection during that time if possible.
Steps
Move the collection.
To move an unsharded collection named inventory
on the
app
database to the shard02
shard, run moveCollection
:
db.adminCommand( { moveCollection: "app.inventory", toShard: "shard02" } )
To get a list of the available shard IDs, run sh.status()
.
For details, see sh.status() Output.
Monitor the progress of the moveCollection operation.
Monitor the time remaining.
To monitor the time remaining for the
moveCollection
operation, use the$currentOp
pipeline stage.This example shows how to check the progress of
moveCollection
on theapp.inventory
collection:db.getSiblingDB("admin").aggregate( [ { $currentOp: { allUsers: true, localOps: false } }, { $match: { type: "op", "originatingCommand.reshardCollection": "app.inventory" } } ] ) Note
To see updated values, you need to continuously run the preceeding pipeline.
The
$currentOp
pipeline outputs:totalOperationTimeElapsedSecs
: elapsed operation time in secondsremainingOperationTimeEstimatedSecs
: estimated time remaining in seconds for the currentmoveCollection
operation. It is returned as-1
when a newmoveCollection
operation starts.
Note
remainingOperationTimeEstimatedSecs
is set to a pessimistic time estimate:- The catch-up phase time estimate is set to the clone phase time, which
- is a relatively long time.
- In practice, if there are only a few pending write operations, the
- actual catch-up phase time is relatively short.
This pipeline stage has output similar to the following:
[ { shard: '<shard>', type: 'op', desc: 'ReshardingRecipientService | ReshardingDonorService | ReshardingCoordinatorService <reshardingUUID>', op: 'command', ns: '<database>.<collection>', originatingCommand: { reshardCollection: '<database>.<collection>', key: <shardkey>, unique: <boolean>, collation: { locale: 'simple' } }, totalOperationTimeElapsedSecs: <number>, remainingOperationTimeEstimatedSecs: <number>, ... }, ... ] Monitor the number of bytes transferred.
To monitor the number of bytes transferred, use
shardingStatistics.resharding.active.bytesCopied
and compare against the number of bytes in the collection.
Confirm the collection has been moved.
To confirm the collection has been moved to the expected shard,
use the $collStats
pipeline stage.
This example shows how to confirm that the app.inventory
collection exists on the expected shard:
db.inventory.aggregate( [ { $collStats: {} }, { $project: { "shard": 1 } } ] )
This pipeline stage has output similar to the following:
[ { shard: 'shard02' } ]