The most surprising thing about a zero-downtime MongoDB upgrade is that it’s often less about the upgrade itself and more about meticulously managing the application’s state and dependencies.

Let’s watch a migration happen. Imagine we have a MongoDB 4.4 replica set, rs0, with three members: mongo1:27017, mongo2:27017, and mongo3:27017. Our application myapp is connected to mongo1:27017 (the primary).

// Initial state: rs0 is on 4.4
{
  "_id": "rs0",
  "version": 1,
  "members": [
    { "_id": 0, "host": "mongo1:27017" },
    { "_id": 1, "host": "mongo2:27017" },
    { "_id": 2, "host": "mongo3:27017" }
  ]
}

We want to upgrade to 6.0 without any application downtime. This means myapp must remain connected and functional throughout the process.

The core strategy is to upgrade members one by one, ensuring the replica set remains available at each step. We’ll leverage MongoDB’s rolling upgrade feature.

Phase 1: Preparing for the Upgrade

First, ensure your application is configured to use replicaSet in its connection string and that it can handle topology changes gracefully. A connection string like mongodb://mongo1:27017,mongo2:27017,mongo3:27017/?replicaSet=rs0 is crucial. Your app should automatically reconnect to a new primary if the current one becomes unavailable.

Phase 2: Upgrading Members (One by One)

  1. Upgrade a Secondary:

    • Stop the MongoDB 4.4 process on one of the secondaries (e.g., mongo2).

    • Install MongoDB 6.0 binaries.

    • Start the MongoDB 6.0 process on mongo2. MongoDB will detect it’s part of an existing replica set and will begin to upgrade its data files and sync with the current primary. You can monitor this with rs.status() on the primary. Look for the upgraded member to rejoin and start syncing.

    • Diagnosis Command: On the primary (mongo1), run rs.status(). Observe the stateStr for mongo2. It should eventually show as STARTUP2 then SECONDARY.

    • Why it works: MongoDB 4.4 secondaries can sync from a 4.4 primary and then be upgraded in place. The 6.0 secondary can read the 4.4 data files and convert them as it syncs.

  2. Upgrade Another Secondary:

    • Repeat step 1 for another secondary (e.g., mongo3).
  3. Upgrade the Primary:

    • Initiate a failover: From the primary (mongo1), run rs.stepDown(60). This gracefully steps down the current primary, forcing a failover to one of the upgraded secondaries. myapp will experience a brief write interruption (a few seconds) as it reconnects to the new primary. This is the only intentional downtime window, and it’s typically very short if your application handles reconnections well.

    • Upgrade the old primary: Once mongo1 is no longer primary, stop its MongoDB 4.4 process, install 6.0 binaries, and start it. It will rejoin the replica set as a secondary.

    • Promote the new primary: Once mongo1 is synced as a secondary, you can optionally step down the current primary again and promote mongo1 back if desired, or simply leave the current primary in place.

    • Diagnosis Command: After rs.stepDown(), run rs.status() on any member. The myStateStr should indicate the new primary.

    • Why it works: Stepping down a primary is a controlled process. The replica set automatically elects a new primary from the available secondaries. The application’s driver detects the primary change and reconnects.

Phase 3: Finalizing the Upgrade

  1. Upgrade featureCompatibilityVersion:
    • Once all members are running MongoDB 6.0 and the replica set is stable, connect to the new primary.

    • Run db.adminCommand({ setFeatureCompatibilityVersion: "6.0" }). This officially enables 6.0-specific features and prevents downgrading.

    • Diagnosis Command: db.version() on any member should show 6.0.x. db.adminCommand({ getParameter: 1, featureCompatibilityVersion: 1 }) should return { "featureCompatibilityVersion" : { "version" : "6.0" }, "ok" : 1 }.

    • Why it works: This command signals to MongoDB that the entire replica set is ready for 6.0 features. Until this is set, the replica set operates in a backward-compatible mode.

Key Considerations for Zero Downtime:

  • Application Driver: Ensure your application’s MongoDB driver is up-to-date and configured for replica set awareness. Older drivers might not handle topology changes as gracefully.
  • Read Concerns: Applications should use appropriate read concerns (e.g., majority) to ensure they are reading from a consistent state, especially during failovers.
  • Write Concerns: Use w: "majority" for writes to ensure durability.
  • Network Stability: A stable network connection between members is paramount.
  • Resource Availability: Ensure sufficient disk I/O, CPU, and memory on all nodes to handle the sync and upgrade process without impacting performance.
  • Testing: Always perform this upgrade process in a staging environment that mirrors your production setup before attempting it on production.

The next challenge you’ll face is understanding how to leverage the new features introduced in MongoDB 6.0, particularly around time-series collections and queryable encryption.

Want structured learning?

Take the full Mongodb course →