The goal of this tutorial is to show a way to backup and restore a MongoDB without the need of using file system snapshots by only using MongoDB shipped tools. In my case I did not have the option to use LVM snapshots, which would have been my primary choice. The restored Cluster will have the same distribution of chunks like it was when the backup was done.

My MongoDB cluster setup looks like this:

  • 2 replicasets
  • Each replicaset added as a shard
  • Each replicaset consists of 1 master, 1 slave and 1 arbiter

You can create a full backup of the MongoDB cluster using:

mongodump --host mongos1 --port 27017

Let’s now simulate a worst case scenario. You lost all hard drives on all server in your Cluster. Starting from scratch with empty server, configure the basic settings like port, replicaset and config server list. Start up all mongod and config server instances. Make sure that there are no write requests on the MongoDB cluster until the import of the structure data is done and the data import starts. You could use a different port for the single mongos that you now need to start, which will handle most of the restore process.

First restore the settings like chunk size:

mongorestore --host mongos1 --port 27017 --drop -d config -c settings dump/config/settings.bson
mongo --host mongos1 --port 27017 --eval 'sh.setBalancerState(false)'

Reinitialize the replicasets:

Initialize replicaset 1:

mongo --host rs1host1 --port 27017
rs.initiate({
    "_id" : "rs1",
    "members" : [
    {
        "_id" : 0,
        "host" : "rs1host1:27017"
    },
    {
        "_id" : 1,
        "host" : "rs1host2:27017"
    }
    ]
})

Check rs.status() until initialization is done:

rs.status()
rs.addArb("rs1host3:27017")
exit

Initialize replicaset 2:

mongo --host rs2host1 --port 27017
rs.initiate({
    "_id" : "rs2",
    "members" : [
    {
        "_id" : 0,
        "host" : "rs2host1:27017"
    },
    {
        "_id" : 1,
        "host" : "rs2host2:27017"
    }
    ]
})

Check rs.status() until initialization is done:

rs.status()
rs.addArb("rs2host3:27017")
exit

Restore the remaining configuration data:

mongorestore --host mongos1 --port 27017 --drop -d admin dump/admin
mongorestore --host mongos1 --port 27017 -d config -c databases dump/config/databases.bson
mongorestore --host mongos1 --port 27017 -d config -c shards dump/config/shards.bson
mongorestore --host mongos1 --port 27017 -d config -c chunks dump/config/chunks.bson
mongorestore --host mongos1 --port 27017 -d config -c collections dump/config/collections.bson
mongorestore --host mongos1 --port 27017 -d config -c tags dump/config/tags.bson

Make sure that all mongos instances get the manually changed new configuration of the Cluster.

mongo --host mongos1 --port 27017 --eval 'db.adminCommand({"flushRouterConfig" : 1})'

The import of the MongoDB internal structures is now done. You can enable inserting to the databases, but don’t enable the balancer yet. Import each database that you wish to restore:

mongorestore --host mongos1 --port 27017 -d database1 dump/database1
mongorestore --host mongos1 --port 27017 -d database2 dump/database2
mongo --host mongos1 --port 27017 --eval 'sh.setBalancerState(true)'

The restore process is now done. Your cluster is in the same state as the time that the backup was done.