← Recipes

阅读中文版本

Rebuild a MongoDB Index Online

Rebuild a fragmented MongoDB index without blocking writes by leveraging rolling index builds on a replica set.

~45 minmongodbdatabasemaintenance

Task

Rebuild a fragmented index safely across replica set members to avoid write downtime.

When to use this

A large index grows fragmented and query latency creeps up, but a full index rebuild would block writes on the primary.

Prerequisites

  • A MongoDB replica set
  • Rolling upgrade ability across members
  • Monitoring for query latency

Steps

1. Rebuild one secondary at a time to avoid impacting the primary.

rs.stepDown();
rs.status().members.map(m => ({ name: m.name, stateStr: m.stateStr }));

Expected output: The member is stepping down so another primary serves writes while the index rebuilds.

2. Rebuild the index on each secondary in turn.

mongosh --eval 'db.orders.reIndex({ keyPattern: { createdAt: 1 } })'

Expected output: Each secondary rebuilds offline from the primary perspective, keeping writes available.

Troubleshooting

Problem

Primary rebuild blocks writes

Solution

Always rebuild secondaries first and only rebuild the primary during a maintenance window.

Problem

Rebuild fails for lack of disk

Solution

Provision space for the new index before dropping the old one.

Limitations

  • Requires a replica set with spare capacity.
  • Rolling rebuilds take longer than an offline rebuild.
  • Does not address index design issues that cause fragmentation.

What this recipe does

Rebuild a fragmented index safely across replica set members to avoid write downtime.

A large index grows fragmented and query latency creeps up, but a full index rebuild would block writes on the primary.

Prerequisites

  • A MongoDB replica set
  • Rolling upgrade ability across members
  • Monitoring for query latency

Procedure

  1. Rebuild one secondary at a time to avoid impacting the primary.
rs.stepDown();
rs.status().members.map(m => ({ name: m.name, stateStr: m.stateStr }));

Expected result: The member is stepping down so another primary serves writes while the index rebuilds.

  1. Rebuild the index on each secondary in turn.
mongosh --eval 'db.orders.reIndex({ keyPattern: { createdAt: 1 } })'

Expected result: Each secondary rebuilds offline from the primary perspective, keeping writes available.

How to confirm it worked

Run the commands above and confirm every expected result in order. If a step does not produce the stated output, use the troubleshooting notes before continuing. A passing run shows each member reports the rebuilt index and query p99 latency returns to baseline without write downtime.

Troubleshooting

Primary rebuild blocks writes — Always rebuild secondaries first and only rebuild the primary during a maintenance window.

Rebuild fails for lack of disk — Provision space for the new index before dropping the old one.

Limitations

  • Requires a replica set with spare capacity.
  • Rolling rebuilds take longer than an offline rebuild.
  • Does not address index design issues that cause fragmentation.