This topic describes how to monitor the progress of tasks that add or remove shard nodes and how to identify abnormal conditions that may block these tasks.
Background information
After you add or remove shard nodes from a sharded cluster instance, the task might remain incomplete for an extended period. The following sections explain how to troubleshoot this issue.
Before you begin, understand the following concepts:
-
Understand the deployment modes of MongoDB replica set instances and sharded cluster instances, and the differences between these architectures. For more information, see Replica set architecture and Sharded cluster architecture.
-
Understand how the MongoDB Balancer works. For more information, see Manage the MongoDB Balancer.
-
Understand how MongoDB divides data. MongoDB partitions data into chunks.
-
Understand common O&M commands for MongoDB sharded cluster instances, such as
sh.status(). -
Understand how to use mongo shell, mongosh, or other visualization tools.
Check task progress
Step 1: Check whether the Balancer is enabled
Chunk migration during shard addition or removal depends on the Balancer. If the Balancer is disabled, the following issues occur:
-
When adding a shard node: Chunk data cannot migrate to the new shard node, and the node cannot handle service traffic.
-
When removing a shard node: Chunks on the target shard cannot migrate away, blocking the removal task.
Enable the Balancer to ensure normal chunk migration. For instructions, see Manage the MongoDB Balancer.
Use one of the following methods to check whether the Balancer is enabled:
-
Method 1: Run the
sh.status()command.If the Balancer is enabled, the output resembles the following example.
... autosplit: Currently enabled: yes balancer: Currently enabled: yes Currently running: yes Balancer active window is set between 08:30 and 11:30 server local time ...If the output shows
“Currently enabled: no”, the Balancer is disabled. -
Method 2: Run the
sh.getBalancerState()command.-
If the command returns
true, the Balancer is enabled. -
If the command returns
false, the Balancer is disabled.
-
Step 2: Check whether the Balancer window is too short
The Balancer controls chunk migration speed and only migrates chunks during its active window. If migration does not finish within the current window, it resumes in the next window until complete. A short window can slow down shard addition or removal tasks. To adjust the Balancer window, see Manage the MongoDB Balancer.
Use one of the following methods to check the Balancer window:
-
Method 1: Run the
sh.status()command.The following example shows a Balancer window from 08:30 to 11:30 local server time (3 hours total).
... autosplit: Currently enabled: yes balancer: Currently enabled: yes Currently running: yes Balancer active window is set between 08:30 and 11:30 server local time ... -
Method 2: Run the
sh.getBalancerWindow()command.The following example clearly displays the window time, especially useful when many sharded collections exist.
{ "start" : "08:30", "stop" : "11:30" }
Step 3: Gather information needed to estimate task progress
For MongoDB versions earlier than 6.0
This section applies to the following versions:
-
MongoDB instances earlier than version 6.0.
-
MongoDB 6.0 instances with a minor engine version earlier than 7.0.1 (baseline version 6.0.3). To check your minor engine version, see MongoDB minor version guide.
Before estimating task progress, obtain Balancer run statistics (success and failure counts) and chunk information for sharded collections awaiting migration.
You can obtain the Balancer's execution results and information about chunks of sharded tables pending migration using the following two methods:
-
Method 1: Use output from the
sh.status()command.Focus on two parts of the
sh.status()output. The first part shows recent Balancer results, as in this example.... balancer: Collections with active migrations: <db>.<collection> started at Wed Sep 27 2023 10:25:21 GMT+0800 (CST) Failed balancer rounds in last 5 attempts: 0 Migration Results for the last 24 hours: 300 : Success databases: ...The second part shows chunk details for sharded collections, as in this example.
... databases: ... { "_id" : "<db>", "primary" : "d-xxxxxxxxxxxxxxx3", "partitioned" : true, "version" : { "uuid" : UUID("3409a337-c370-4425-ad72-8b8c6b0abd52"), "lastMod" : 1 } } <db>.<collection> shard key: { "<shard_key>" : "hashed" } unique: false balancing: true chunks: d-xxxxxxxxxxxxxxx1 13630 d-xxxxxxxxxxxxxxx2 13629 d-xxxxxxxxxxxxxxx3 13652 d-xxxxxxxxxxxxxxx4 13630 d-xxxxxxxxxxxxxxx5 3719 too many chunks to print, use verbose if you want to force print ...In this example, “d-xxxxxxxxxxxxxxx5” is the newly added shard node. You can also run the
getShardDistributioncommand in the database containing the sharded collection to obtain chunk distribution details, as shown below.use <db> db.<collection>.getShardDistribution() -
Method 2: Read relevant data directly from the config database.
View chunk statistics aggregated by shard as follows.
db.getSiblingDB("config").chunks.aggregate([{$group: {_id: "$shard", count: {$sum: 1}}}])To view chunks on a specific shard grouped by namespace, run the following command.
db.getSiblingDB("config").chunks.aggregate([{$match: {shard: "d-xxxxxxxxxxxxxx"}},{$group: {_id: "$ns", count: {$sum: 1}}}])To count chunks successfully migrated to a specific shard node in the past 24 hours, run the following command.
// details.to specifies the destination shard for chunk migration // Use ISODate to define the time range in the time field db.getSiblingDB("config").changelog.find({"what" : "moveChunk.commit", "details.to" : "d-xxxxxxxxxxxxx","time" : {"$gte": ISODate("2023-09-26T00:00:00")}}).count()
For MongoDB versions 6.0 and later
This section applies to the following versions:
-
MongoDB instances version 6.0 and later.
-
MongoDB 6.0 instances with a minor engine version 7.0.1 (baseline version 6.0.3) or later. To check your minor engine version, see MongoDB minor version guide.
Before estimating task progress, focus on data distribution across shards. You can still use sh.status() output as a reference, but shift attention from uneven chunk counts to actual data volume distribution.
-
Obtain sharded collection distribution and data balance information.
Use the
getShardDistributioncommand to obtain distribution details and focus on data balance. Example:mongos> db.xxx.getShardDistribution() Shard d-xxx at xxx data : 379.26MiB docs : 8277367 chunks : 1 estimated data per chunk : 379.26MiB estimated docs per chunk : 8277367 Shard d-xxx at xxx data : 379.11MiB docs : 8272852 chunks : 1 estimated data per chunk : 379.11MiB estimated docs per chunk : 8272852 Shard d-xxx at xxx data : 379.18MiB docs : 8275108 chunks : 1 estimated data per chunk : 379.18MiB estimated docs per chunk : 8275108 Totals data : 1.11GiB docs : 24825327 chunks : 3 Shard d-xxx contains 33.34% data, 33.34% docs in cluster, avg obj size on shard : 48B Shard d-xxx contains 33.32% data, 33.32% docs in cluster, avg obj size on shard : 48B Shard d-xxx contains 33.33% data, 33.33% docs in cluster, avg obj size on shard : 48BYou can also run the following command for more detailed distribution information (including document count, total size, orphaned document count, and orphaned size):
db.getSiblingDB("admin").aggregate( [{ $shardedDataDistribution: { } },{ $match: { "ns": "<db>.<collection>" } }] ).pretty()The following example output shows noticeable data imbalance across shards.
{ "ns" : "<db>.<collection>", "shards" : [ { "shardName" : "d-xxxxxxxxxxxxxxx1", "numOrphanedDocs" : 0, "numOwnedDocuments" : 504298920, "ownedSizeBytes" : NumberLong("833101815840"), "orphanedSizeBytes" : 0 }, { "shardName" : "d-xxxxxxxxxxxxxxx2", "numOrphanedDocs" : 0, "numOwnedDocuments" : 250283901, "ownedSizeBytes" : NumberLong("409714745937"), "orphanedSizeBytes" : 0 }, { "shardName" : "d-xxxxxxxxxxxxxxx3", "numOrphanedDocs" : 0, "numOwnedDocuments" : 109098088, "ownedSizeBytes" : NumberLong("178157177704"), "orphanedSizeBytes" : 0 }, { "shardName" : "d-xxxxxxxxxxxxxxx4", "numOrphanedDocs" : 0, "numOwnedDocuments" : 382018055, "ownedSizeBytes" : NumberLong("630329790750"), "orphanedSizeBytes" : 0 } ] }From this output, you can determine that the instance has 4 shard nodes and the total data volume for the sharded collection
<db>.<collection>is approximately 2051303530231 bytes (833101815840 + 409714745937 + 178157177704 + 630329790750 = 2051303530231), or about 1910.4 GB. -
View successfully migrated data volume over the past day.
Run the following query:
pipeline = [ { '$match': { 'what': 'moveChunk.commit', } }, { '$group': { '_id': { 'date': { '$dateToString': { 'format': '%Y-%m-%d', 'date': '$time'} }, }, 'chunks_moved': { '$sum': 1 }, 'docs_moved': { '$sum': '$details.counts.cloned' }, 'bytes_moved': { '$sum': '$details.counts.clonedBytes' }, } }, { '$sort': { '_id.date': -1} }, ] db.getSiblingDB("config").changelog.aggregate(pipeline)Example output:
mongos> db.getSiblingDB("config").changelog.aggregate(pipeline) { "_id" : { "date" : "2024-09-24" }, "chunks_moved" : 91, "docs_moved" : NumberLong(33071040), "bytes_moved" : NumberLong("11532786734") } { "_id" : { "date" : "2024-09-23" }, "chunks_moved" : 294, "docs_moved" : NumberLong(109806635), "bytes_moved" : NumberLong("38294757573") } { "_id" : { "date" : "2024-09-22" }, "chunks_moved" : 737, "docs_moved" : NumberLong(266800041), "bytes_moved" : NumberLong("93047288531") } { "_id" : { "date" : "2024-09-21" }, "chunks_moved" : 1448, "docs_moved" : NumberLong(525308393), "bytes_moved" : NumberLong("183117965820") } { "_id" : { "date" : "2024-09-20" }, "chunks_moved" : 1459, "docs_moved" : NumberLong(530020503), "bytes_moved" : NumberLong("184390749022") } { "_id" : { "date" : "2024-09-19" }, "chunks_moved" : 1478, "docs_moved" : NumberLong(557833705), "bytes_moved" : NumberLong("186910196651") } { "_id" : { "date" : "2024-09-18" }, "chunks_moved" : 1360, "docs_moved" : NumberLong(508484825), "bytes_moved" : NumberLong("173486932689") }This output shows that on
2024-09-21, 183117965820 bytes (about 170.5 GB) were migrated.
Step 4: Estimate task progress and completion time
For MongoDB versions earlier than 6.0
This section applies to the following versions:
-
MongoDB instances earlier than version 6.0.
-
MongoDB 6.0 instances with a minor engine version earlier than 7.0.1 (baseline version 6.0.3). To check your minor engine version, see MongoDB minor version guide.
After obtaining the number of successfully migrated chunks and current data distribution, estimate overall task progress and expected completion time.
Assume the following ideal conditions during shard addition: total chunk count remains constant, shard count stays fixed (no concurrent shard additions or removals), service load remains stable, and Balancer parameters use default values. Using the example from Step 3 under For MongoDB versions earlier than 6.0, you know:
-
There are 5 shard nodes.
-
300 chunks migrated successfully during the Balancer window.
-
The sharded collection
<db>.<collection>has 58260 total chunks (13630 + 13629 + 13652 + 13630 + 3719 = 58260).
Therefore, the following can be calculated:
-
At equilibrium, each shard should hold 11652 chunks (58260 ÷ 5 = 11652).
-
At the current migration rate, task completion requires another 26.4 days ((11652 – 3719) ÷ 300 ≈ 26.4).
-
The shard addition task is 32% complete (3719 ÷ 11652 = 32%).
In real-world scenarios, total chunk count increases due to ongoing writes and chunk splits. This calculation assumes ideal conditions; actual completion time may be longer.
For MongoDB versions 6.0 and later
This section applies to the following versions:
-
MongoDB instances version 6.0 and later.
-
MongoDB 6.0 instances with a minor engine version 7.0.1 (baseline version 6.0.3) or later. To check your minor engine version, see MongoDB minor version guide.
Assume the sharded cluster instance has only one collection requiring balancing. Using the example from Step 3 under For MongoDB versions 6.0 and later, you know:
-
There are 4 shard nodes.
-
On
2024-09-21, approximately 170.5 GB (183117965820 bytes) were migrated. -
The sharded collection
<db>.<collection>has a total data volume of about 1910.4 GB (2051303530231 bytes).
Therefore, the following can be calculated:
-
At equilibrium, each shard should hold roughly 477.6 GB (512825882557.75 bytes).
-
The total data volume needing migration to reach equilibrium is 875559682949 bytes (815.4 GB), broken down as follows:
Shard1 needs to migrate 320275933282.25 bytes (833101815840 – 512825882557.75).
Shard2 needs to migrate 103111136620.75 bytes (409714745937 – 512825882557.75).
Shard3 needs to migrate 334668704853.75 bytes (178157177704 – 512825882557.75).
Shard4 needs to migrate 117503908192.25 bytes (630329790750 – 512825882557.75).
(320275933282.25 + 103111136620.75 + 334668704853.75 + 117503908192.25 = 875559682949)
-
At the current migration rate, equilibrium will be reached in about 4.8 days (815.4 GB ÷ 170.5 GB/day ≈ 4.8 days).
Step 5: Confirm whether the task flow is blocked (shard removal)
If a shard removal task is blocked, running sh.status() shows no successful chunk migrations in recent history, and the target shard still holds unmigrated chunks. This prevents task completion and blocks other O&M operations in the ApsaraDB for MongoDB console.
The following example shows typical sh.status() output for this scenario.
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: no
Balancer lock taken at Wed Sep 30 2020 02:03:11 GMT+0800 (CST) by ConfigServer:Balancer
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
No recent migrations
databases:
{ "_id" : "report", "primary" : "d-0xixxx", "partitioned" : true }
report.report
shard key: { "GsId" : "hashed" }
unique: false
balancing: true
chunks:
d-0xixxx 9
d-0xixxx 2133
d-0xixxx 2152
d-0xixxx 2116
d-0xixxx 2133
too many chunks to print, use verbose if you want to force print
This issue often occurs because jumbo chunks block shard removal. Confirm this by running the following command.
db.getSiblingDB("config").chunks.aggregate([{$match: {shard: "d-xxxxxxxxxxxxxx", jumbo:true}},{$group: {_id: "$ns", count: {$sum: 1}}}])
Jumbo chunks usually result from poor shard key design (such as hot keys). Try these solutions:
-
If your MongoDB major version is 4.4, use the refineCollectionShardKey command to improve your shard key design by appending suffixes to increase cardinality and resolve jumbo chunks.
-
If your MongoDB major version is 5.0 or later, use the reshardCollection command to re-shard the collection with a new shard key. For more information, see Reshard a Collection.
-
If you can safely delete some business data, remove data from the jumbo chunk. This reduces its size, potentially converting it to a regular chunk that the Balancer can migrate.
-
Increase the
chunkSizeparameter to change jumbo chunk detection criteria. Perform this adjustment only with assistance from Alibaba Cloud technical support engineers.
If none of these methods work, submit a ticket to contact technical support.
Accelerate adding or deleting task processes
To complete shard addition or removal faster, try these acceleration methods:
-
Increase the Balancer window duration. Note that chunk migration adds extra load that may affect your service. Assess risks before adjusting. For instructions, see Manage the MongoDB Balancer.
-
Adjust the setParameter.chunkMigrationConcurrency parameter to change chunk migration concurrency. For details, see Parameter tuning recommendations.
-
Manually run
moveChunkoperations during off-peak hours. For more information, see sh.moveChunk(). Example:sh.moveChunk("<db>.<collection>", {"<shard_key>": <value>}, "d-xxxxxxxxxxxxx") // example: sh.moveChunk("records.people", { zipcode: "53187" }, "shard0019") -
submit a ticket to request technical support for kernel parameter adjustments.