MongoDB Mastery
MongoDB Mastery lessons / Module 26: Backup & Restore

Percona Backup for MongoDB: logical, physical and PITR

Level 4: Database Engineer25 min

Run consistent backups of replica sets and sharded clusters with PBM, enable point-in-time recovery from oplog slices, and rehearse restores.

This lesson is interactive. Run every example against an in-browser MongoDB, see explain() plans drawn as trees, and take the quiz.
Open the interactive lesson
You will learn to
  • Describe PBM architecture: agents, storage, control collections
  • Choose logical, physical or incremental backups
  • Enable PITR and restore to a timestamp
  • Run and validate a restore drill

conceptThe concept

Percona Backup for MongoDB (PBM) is an open-source backup tool for replica sets and sharded clusters. A pbm-agent runs next to every mongod; you drive it with the pbm CLI. Agents coordinate through control collections in the admin database and write to remote storage (S3-compatible, GCS, Azure Blob or a shared filesystem).

TypeHowBest for
LogicalExports documents and replays the oplog for consistencySmall and medium data, selective restore of namespaces, version changes
PhysicalCopies WiredTiger files through a backup cursor (Percona Server for MongoDB)Large data sets; restore time close to copy time
Incremental physicalCopies only changed blocks since the baseVery large data with frequent backups
PITRAgents continuously upload oplog slicesRestoring to just before a bad operation

For sharded clusters PBM produces a backup that is consistent across shards and the config server replica set.

whyWhy it matters

mongodump alone is not consistent across shards, is slow on large data and has no point-in-time capability. A self-hosted MongoDB estate needs scheduled backups, PITR and tested restores; PBM provides that without a commercial licence, and it is what the Percona Operator uses on Kubernetes.

Use caseReal-world scenario

At 14:05 a script runs deleteMany({}) on orders. The DBA lists backups, picks the nightly physical backup, and restores to 14:04:59 on a staging cluster with pbm restore --time. After validating counts, the orders collection is copied back to production. Total time: 40 minutes, data loss: zero.

Try itExamples

Run and edit these in the interactive lesson.

Configure storage and PITR
# /etc/pbm/pbm_config.yaml
storage:
  type: s3
  s3:
    region: ap-south-1
    bucket: acme-mongo-backups
    prefix: prod-rs0
pitr:
  enabled: true
  oplogSpanMin: 10

export PBM_MONGODB_URI="mongodb://pbmuser:****@localhost:27017/?authSource=admin&replSetName=rs0"
pbm config --file /etc/pbm/pbm_config.yaml
pbm status
Back up, list and restore
pbm backup --type=physical          # or logical, incremental --base
pbm list                            # snapshots and the PITR timeline
pbm restore 2026-10-07T23:00:12Z    # full restore of one snapshot
pbm restore --time="2026-10-08T14:04:59"            # point in time
pbm restore 2026-10-07T23:00:12Z --ns=shop.orders   # selective (logical backups)
pbm logs --tail=50
The PBM user (run once on each replica set)
use admin
try { db.dropUser("pbmuser") } catch (e) {}
try { db.dropRole("pbmAnyAction") } catch (e) {}
db.createRole({ role: "pbmAnyAction", privileges: [{ resource: { anyResource: true }, actions: ["anyAction"] }], roles: [] })
db.createUser({ user: "pbmuser", pwd: "change-me", roles: ["backup", "clusterMonitor", "restore", { role: "pbmAnyAction", db: "admin" }] })
db.getUser("pbmuser").roles.map(r => r.role)
Restore validation: counts and a content fingerprint
const summary = db.getCollectionNames().filter(c => !c.startsWith("system.") && !c.startsWith("lab_"))
  .map(c => ({ coll: c, docs: db.getCollection(c).countDocuments(), indexes: db.getCollection(c).getIndexes().length }));
summary
Run the same query on the source (or record it before the incident) and on the restored cluster, then compare.

internalsUnder the hood

With PITR enabled, one agent per replica set uploads the oplog in chunks (10 minutes by default). A PITR restore applies the base backup, then replays slices up to the requested time; the timeline is only continuous if PITR has been running since the last base backup. During a physical restore PBM stops the mongod processes and replaces their data, so restores are disruptive and require agents on every node. Users and roles are part of the backup, which matters when restoring into a different cluster.

Avoid / preferDo this, not that

Avoid
# backups to a bucket, never restored
pbm backup --type=logical
Prefer
# scheduled backups plus a regular restore drill into a scratch cluster
pbm backup --type=physical
pbm list
pbm restore <backup_name>   # on the drill cluster, then verify counts

A backup you have never restored is a hope, not a plan. Drills find missing permissions, wrong storage settings and slow restore times before an incident does.

Avoid
pbm config --set pitr.enabled=false   # base backups only
Prefer
pbm config --set pitr.enabled=true
pbm restore --time="2026-10-08T09:15:00"

Base backups alone lose everything since the last backup. With PITR, PBM saves oplog slices continuously so you can restore to just before the bad write.

PitfallsCommon mistakes

  • Running pbm-agent on only some nodes; every mongod needs an agent.
  • Never testing a restore, so the first attempt happens during an incident.
  • Disabling PITR temporarily and not noticing the gap in the timeline.
  • Restoring a physical backup straight over production instead of a side cluster when only one collection is damaged.

LimitsWhen not to use it

PBM backs up replica sets and sharded clusters with consistent cluster-wide snapshots. For a single small database where minutes of loss are acceptable, a scheduled mongodump may be enough. Physical backups are fast for large data sets but restore only to the same major version and need the cluster stopped during restore.

SecuritySecurity notes

The PBM user needs backup and restore privileges on the whole cluster; keep its credentials out of shell history and scripts. Lock down the storage bucket (no public access, versioning or object lock against deletion, server-side encryption), because the backups contain every document.

ChallengeTry it yourself

Write the PBM commands to enable PITR, take a physical backup, list backups and restore to 09:15 today.

Show one solution
One solution
pbm config --file /etc/pbm/pbm-config.yaml
pbm config --set pitr.enabled=true
pbm backup --type=physical
pbm list
pbm restore --time="2026-10-08T09:15:00"
Run on a host with pbm installed and PBM_MONGODB_URI set; pbm-agent must run next to every mongod.

InterviewQuestions you should be able to answer

How would you recover from an accidental deleteMany on a self-hosted replica set?

Find the exact time from the oplog (op: "d" burst on that namespace). With PBM and PITR enabled, restore the last base backup plus oplog up to one second before the delete onto a staging cluster (pbm restore --time), validate, and copy the collection back. Without PITR, restore the last snapshot and replay the oplog manually with mongorestore --oplogReplay --oplogLimit. Afterwards, restrict delete privileges and rehearse restores.

QuizCheck your understanding

4 questions with instant feedback in the interactive lesson; a wrong answer goes into your review deck.