Building indexes with replica sets

Version 2.1.0 and later

Indexes can be built in the foreground or background. Background indexes builds on the primary will result in background index builds on the secondaries.

Index built on primary Index built on secondary Index built on recovering member
Foreground Foreground Foreground
Background Background Foreground

Recovering members (for example, new members who are initial syncing or members in maintenance mode) will always build indexes in the foreground because they cannot handle reads anyway. Generally you want recovering members to catch up as quickly as possible.

Version 2.0.x and earlier

Building an index with a replica set would be straightforward except that index build operations are blocking. The build index operation replicates from primaries to secondaries. This section discusses how to build an index on a live system.

If the collection to index is tiny, simply index it – the time to index would be short enough that the obstruction is not significant. (Be sure to verify the collection is small.)

Note that the background indexing option has a significant limitation and runs in background mode only on the primary. Thus, for now, the following procedure is recommended instead.

Building an index one replica set member at a time

This is a manual process where we take the members of a set offline one at a time to build the index. Suppose we wish to create on index on the name field in our logins collection, and that we have a three member replica set using hostnames a, b, and c.

  • First check the entire replica set is healthy by running rs.status() in the mongo shell.
  • Next, build the necessary index on one secondary at a time.
  • For each secondary:
    • Shutdown the mongod process on that member.
    • Verify the rest of the set is still healthy by running rs.status() while connected to one of the other members. Also, before continuing, verify the members have sufficient capacity while this member is down.
    • Restart the local mongod in "maintenance mode" by starting it without -replSet and on a different port number (-port so that clients to not try to connect to it.
    • Connect from the shell to the mongod mentioned above.
    • Build the index:
      db.logins.ensureIndex({name: 1})
    • After completion, shut down the mongod process.
    • Restart the mongod with its normal parameters which include the --replSet parameter.
    • Use rs.status() to check that the cluster is healthy all around.
    • Repeat for the next secondary.

Now that all the secondaries have the index you can choose to either build the index on the primary in background mode, which will take longer and put more load on primary, or follow the steps below to demote the primary so you can build in the foreground (the default option) more quickly and without affecting the primary.

Once you've built the index on each secondary, you'll have to step down the primary node and do the same. Connect to the primary and then run rs.stepDown(). Once the primary has safely stepped down, check to see that a new secondary has been elected primary.

Note that when a member that was primary goes offline on its shutdown above, there will be a short window, until another member takes over, where there is no primary for the entire cluster. Therefore, you may have to momentarily put your application into a maintenance mode before you step down the primary so that the stepping down does not result in application exceptions, poor user experience, etc.

With the primary in secondary mode, you can now follow the steps above to create the necessary index.

Follow @mongodb

MongoDB Pittsburgh - May 15
MongoNYC - May 23
MongoDB Paris - Jun 14
MongoDB UK - Jun 20
MongoDC - June 26


Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

PLEASE POST QUESTIONS IN THE USER GROUPS FORUM. Post non-question comments and helpful hints here.

blog comments powered by Disqus