Backups sind Versicherung gegen das Unvorstellbare.
Hardware-Failures, Software-Bugs, Human-Errors, Ransomware-Attacks – all
dies kann Production-Daten vernichten. Ein versehentlicher
db.collection.drop() auf der falschen Database. Ein Bug,
der Millionen Dokumente korrupt. Ein Datacenter-Brand. Diese Szenarien
sind selten, aber nicht unmöglich. Wenn sie passieren, ist ein
funktionierendes Backup der Unterschied zwischen “Daten restored in 2
Stunden” und “Business bankrupt”.
Aber Backups sind nutzlos wenn sie nicht getestet sind. Die berüchtigtste Backup-Geschichte in Tech: GitLab’s 2017 Incident, wo ein Engineer versehentlich eine Production-Database dropped. Backups existierten – aber fünf verschiedene Backup-Systeme hatten alle Failures, und nur 6 Stunden Data konnten recovered werden aus 18 Stunden. Der Post-Mortem: “Backups wurden nie getestet.” Dies ist die kritische Lesson: Backups existieren ist nicht genug – sie müssen regelmäßig tested und validated werden.
Dieses Kapitel behandelt Backup-Strategien systematisch – von simple mongodump für kleine Databases über Filesystem-Snapshots für large-scale bis zu Point-in-Time-Recovery für Enterprise-Requirements. Der Fokus ist auf Production-Ready-Solutions mit emphasis auf Testing und Disaster-Recovery-Planning.
Bevor man eine Backup-Strategy wählt, muss man zwei Metriken definieren:
Recovery Time Objective (RTO): Wie schnell muss die Database restored werden? 1 Stunde? 24 Stunden? Eine Woche?
Recovery Point Objective (RPO): Wie viel Data-Loss ist akzeptabel? Null Data-Loss? 1 Stunde? 24 Stunden?
Diese definieren die Backup-Frequency und -Method:
| RPO | Backup-Frequency | Method |
|---|---|---|
| 24 hours | Daily | mongodump, Filesystem-Snapshot |
| 1 hour | Hourly | Continuous-Backup (Oplog), Snapshots |
| < 1 minute | Continuous | Replica-Sets mit delayed-members, Point-in-Time |
| Zero (keine Data-Loss) | Real-Time | Geographically-distributed Replica-Sets |
Für ein E-Commerce-System während Black-Friday könnte RPO = 1 Minute sein (jede Minute Data-Loss = tausende verlorene Orders). Für ein Internal-Tool könnte RPO = 24 Stunden akzeptabel sein.
RTO bestimmt die Restore-Speed. Wenn RTO = 1 Stunde, braucht man fast-restores – etwa Filesystem-Snapshots oder Hot-Standby-Replicas. Wenn RTO = 24 Stunden, kann man langsamer aber günstigere Methods nutzen – etwa Tape-Backups oder Cold-Storage.
mongodump ist MongoDB’s built-in Backup-Tool. Es
exportiert Database-Content zu BSON-Files – ein logical Backup, nicht
ein Physical-Copy.
# Backup entire database
mongodump --uri="mongodb://user:pass@host:27017/mydb" --out=/backup/mongodb-$(date +%Y%m%d)
# Backup specific collection
mongodump --uri="mongodb://user:pass@host:27017/mydb" --collection=users --out=/backup/users-$(date +%Y%m%d)
# Backup mit Compression
mongodump --uri="mongodb://user:pass@host:27017/mydb" --gzip --out=/backup/mongodb-$(date +%Y%m%d)Dies created eine Directory-Structure:
/backup/mongodb-20240120/
├── mydb/
│ ├── users.bson
│ ├── users.metadata.json
│ ├── orders.bson
│ ├── orders.metadata.json
│ └── ...
Restore:
# Restore entire database
mongorestore --uri="mongodb://user:pass@host:27017" --drop /backup/mongodb-20240120
# Restore specific collection
mongorestore --uri="mongodb://user:pass@host:27017/mydb" --collection=users /backup/mongodb-20240120/mydb/users.bsonDer --drop-Flag droppt existierende Collections vor
Restore – ohne ihn merged mongorestore neue Daten mit existierenden (was
meist unerwünscht ist).
mongodump Characteristics:
Pros: - Simple und intuitive - Granular: Kann
einzelne Collections backupen - Platform-Independent: BSON-Files
funktionieren cross-platform - Compressed: Mit --gzip spart
Speicher
Cons: - Langsam bei großen Databases (GB-scale ist OK, TB-scale problematisch) - Nicht atomic: Backup reflektiert nicht einen Single-Point-in-Time wenn Database während Backup modifiziert wird - Kein Built-in-Encryption: Backup-Files sind unencrypted (kann via Filesystem-Encryption gehandelt werden)
Use-Case:
mongodump ist perfekt für: - Small-to-Medium Databases (< 100 GB) - Development/Staging-Environments - Selective-Collection-Backups - Database-Migrations zwischen Environments
Für Large-Scale-Production oder Databases mit < 1-Hour-RPO ist mongodump oft nicht ausreichend.
Filesystem-Snapshots sind Copy-on-Write-Clones des Database-Directories. Modern Filesystems (LVM, ZFS, XFS, Btrfs) und Cloud-Storage (AWS-EBS, GCP-Persistent-Disks) unterstützen Snapshots – sie sind near-instant, selbst für TB-scale-Databases.
Vorgehen:
# 1. Ensure Journaling ist enabled (Default seit MongoDB 4.0)
# Journaling garantiert Crash-Consistency
# 2. Optional: Flush und lock (nur nötig wenn Journaling disabled)
mongosh --eval "db.fsyncLock()"
# 3. Create Snapshot (AWS EBS example)
aws ec2 create-snapshot --volume-id vol-1234567890abcdef0 --description "MongoDB backup 2024-01-20"
# 4. Unlock (wenn locked)
mongosh --eval "db.fsyncUnlock()"Der Snapshot ist ein Point-in-Time-Copy. MongoDB muss nicht gestoppt werden – dank Journaling ist der Snapshot crash-consistent (wie nach einem unerwarteten Shutdown – MongoDB kann recovern via Journal-Replay).
Restore from Snapshot:
# 1. Stop MongoDB
sudo systemctl stop mongod
# 2. Create Volume from Snapshot
aws ec2 create-volume --snapshot-id snap-1234567890abcdef0 --availability-zone us-east-1a
# 3. Attach Volume zum Server
aws ec2 attach-volume --volume-id vol-0987654321fedcba0 --instance-id i-1234567890abcdef0 --device /dev/sdf
# 4. Mount Volume
sudo mount /dev/sdf /var/lib/mongodb
# 5. Start MongoDB
sudo systemctl start mongodMongoDB startet, replayed das Journal (wenn nötig), und ist operational.
Snapshot-Performance:
Snapshots sind orders-of-magnitude schneller als mongodump:
| Method | 100 GB Database | 1 TB Database |
|---|---|---|
| mongodump | ~30 minutes | ~5 hours |
| Filesystem-Snapshot | < 1 minute | < 1 minute |
Snapshot-Limitations:
Use-Case:
Snapshots sind optimal für: - Large Databases (> 100 GB) - Low-RTO-Requirements (< 1 hour) - Cloud-Hosted-MongoDB (AWS, GCP, Azure) - Full-Database-Backups
In Replica-Sets kann man Backups vom Secondary-Node nehmen ohne Primary-Performance zu beeinträchtigen.
Strategy:
// 1. Identify a Secondary
rs.status().members.forEach(m => {
if (m.stateStr === "SECONDARY") {
print(`Secondary: ${m.name}`)
}
})
// 2. Optionally: Set priority to 0 (verhindert dass dieser Secondary Primary wird)
cfg = rs.conf()
cfg.members[2].priority = 0
cfg.members[2].hidden = true // Versteckt von Clients
rs.reconfig(cfg)
// 3. Connect to Secondary und backupDann führe mongodump oder Filesystem-Snapshot auf dem Secondary aus. Der Primary ist nicht betroffen – Writes und Reads laufen normal.
Hidden-Members für Backups:
Eine Best-Practice ist ein dedicated Hidden-Member nur für Backups:
rs.add({
host: "backup-node:27017",
priority: 0,
hidden: true,
votes: 0 // Participiert nicht in Elections
})Dieser Node repliziert Data from Primary, ist aber invisible to Clients und participiert nicht in Elections. Er existiert nur für Backups und Analytics-Queries.
Delayed-Members für Point-in-Time-Recovery:
Ein Delayed-Member repliziert Data mit einem Time-Delay – etwa 1 Stunde oder 24 Stunden:
rs.add({
host: "delayed-node:27017",
priority: 0,
hidden: true,
votes: 0,
slaveDelay: 3600 // 1 hour delay
})Wenn jemand versehentlich eine Collection dropt um 14:00, kann man um 14:30 zum Delayed-Member connecten, wo die Collection noch existiert (weil der Node 1 Stunde hinterher ist). Man kann die Data exportieren und zum Primary restoren.
Limitation:
Delayed-Members schützen nur gegen Human-Errors oder Software-Bugs, die sofort detektiert werden. Wenn ein Corruption-Bug langsam über Wochen Daten korrupt, hilft ein 1-Hour-Delayed-Member nicht.
Sharded-Clusters sind komplex – Data ist über multiple Shards distributed, Metadata ist in Config-Servers. Ein konsistentes Backup erfordert Coordination.
Challenge:
Wenn man jeden Shard separat zu unterschiedlichen Zeiten backupt, ist das Backup inconsistent. Beispiel: - 10:00 AM: Backup Shard A - 10:30 AM: Backup Shard B - Zwischen 10:00 und 10:30: Ein Dokument moved von Shard A zu Shard B via Balancer
Das Dokument könnte in beiden Backups sein (duplicate) oder in keinem (verloren).
Solution 1: Stop Balancer:
// 1. Stop Balancer
sh.stopBalancer()
// 2. Backup Config-Servers (critical!)
mongodump --uri="mongodb://config-server:27019" --out=/backup/config
// 3. Backup each Shard (parallel möglich)
mongodump --uri="mongodb://shard1:27017" --out=/backup/shard1
mongodump --uri="mongodb://shard2:27017" --out=/backup/shard2
// 4. Start Balancer
sh.startBalancer()Während Balancer gestoppt ist, bewegen sich keine Chunks – das Backup ist consistent.
Solution 2: Filesystem-Snapshots mit Coordination:
# 1. Stop Balancer
# 2. Flush all Shards und Config-Servers
# 3. Create Snapshots simultaneously (scripted)
# 4. Unlock and start BalancerConfig-Server-Backup ist kritisch:
Die Config-Servers enthalten Cluster-Metadata – welche Chunks auf welchem Shard, Shard-Ranges, etc. Ohne Config-Server-Backup kann man die Shard-Backups nicht korrekt restoren.
Restore-Process:
# 1. Restore Config-Servers first
mongorestore --uri="mongodb://config-server:27019" /backup/config
# 2. Restore each Shard
mongorestore --uri="mongodb://shard1:27017" /backup/shard1
mongorestore --uri="mongodb://shard2:27017" /backup/shard2
# 3. Restart mongos routersDas Oplog (Operations-Log) ist das Replication-Journal – jede Write-Operation wird in Oplog logged. Durch Backup des Oplogs + einem Base-Backup kann man zu jedem Point-in-Time restoren.
Oplog-Backup with mongodump:
# Base Backup
mongodump --uri="mongodb://host:27017/mydb" --out=/backup/base-20240120
# Continuous Oplog Backup
mongodump --uri="mongodb://host:27017" --oplog --out=/backup/oplog-$(date +%Y%m%d-%H%M%S)Der --oplog-Flag inkludiert Oplog-Entries seit
Backup-Start bis Backup-End.
Point-in-Time-Restore:
# 1. Restore Base-Backup
mongorestore --uri="mongodb://host:27017" --drop /backup/base-20240120
# 2. Replay Oplog bis gewünschtem Timestamp
mongorestore --uri="mongodb://host:27017" --oplogReplay --oplogLimit="1705756800:0" /backup/oplog-*Der --oplogLimit ist ein Timestamp (seconds:increment
seit Epoch). MongoDB replayed alle Oplog-Entries bis zu diesem
Point.
Use-Case:
Um 14:00 wird entdeckt, dass ein Bug seit 13:30 Daten korrupt. Man kann restoren zu 13:29:59 – dem letzten guten State.
Enterprise-Tools für Continuous-Backup:
MongoDB Atlas und Ops-Manager haben Continuous-Backup built-in – sie backupen Oplogs kontinuierlich und erlauben Point-in-Time-Restore via UI:
Atlas UI > Backups > Restore > Select timestamp: 2024-01-20 13:29:59
Für self-hosted MongoDB kann man Percona-Backup nutzen, das ähnliche Continuous-Backup-Capabilities hat.
Ein Backup, das nie getestet wurde, ist potenziell wertlos. Die einzige Garantie, dass ein Backup funktioniert, ist successful Restore.
Testing-Strategy:
#!/bin/bash
# backup-test.sh
# 1. Create Backup
mongodump --uri="$PROD_URI" --out=/backup/test-$(date +%Y%m%d)
# 2. Provision Test-Server
# (Script oder Manual)
# 3. Restore to Test-Server
mongorestore --uri="$TEST_URI" --drop /backup/test-$(date +%Y%m%d)
# 4. Validate Restore
# - Connect to Test-Server
# - Run smoke-tests: Check collection counts, sample queries
TEST_COUNT=$(mongosh $TEST_URI --quiet --eval "db.users.countDocuments()")
PROD_COUNT=$(mongosh $PROD_URI --quiet --eval "db.users.countDocuments()")
if [ "$TEST_COUNT" -ne "$PROD_COUNT" ]; then
echo "ERROR: Restore validation failed"
exit 1
fi
echo "Backup-Test successful"
# 5. Cleanup
# Drop Test-Database oder Delete Test-ServerDieses Script sollte regelmäßig laufen – etwa weekly oder monthly. Wenn es failed, ist das ein Alert – Backup-Strategy muss fixed werden.
Restore-Time-Testing:
Neben Correctness sollte man auch Restore-Time messen:
# Measure Restore-Time
START=$(date +%s)
mongorestore --uri="$TEST_URI" /backup/test-$(date +%Y%m%d)
END=$(date +%s)
DURATION=$((END - START))
echo "Restore took $DURATION seconds"
# Validate RTO
if [ "$DURATION" -gt 3600 ]; then # RTO = 1 hour
echo "WARNING: Restore exceeded RTO"
fiWenn Restore-Time steigt (etwa wegen Database-Growth), muss man Backup-Strategy anpassen.
Backups sollten nicht forever retained werden – Storage ist teuer. Eine typische Retention-Policy:
| Backup-Type | Retention |
|---|---|
| Hourly | 7 days |
| Daily | 30 days |
| Weekly | 90 days |
| Monthly | 1 year |
| Yearly | 7 years (Compliance) |
Automated-Cleanup:
#!/bin/bash
# cleanup-old-backups.sh
BACKUP_DIR=/backup/mongodb
# Delete hourly backups older than 7 days
find $BACKUP_DIR/hourly -type d -mtime +7 -exec rm -rf {} \;
# Delete daily backups older than 30 days
find $BACKUP_DIR/daily -type d -mtime +30 -exec rm -rf {} \;
# Delete weekly backups older than 90 days
find $BACKUP_DIR/weekly -type d -mtime +90 -exec rm -rf {} \;
# Delete monthly backups older than 365 days
find $BACKUP_DIR/monthly -type d -mtime +365 -exec rm -rf {} \;Dieses Script läuft täglich und cleaned expired Backups.
Backups enthalten sensitive Data – Passwords, PII, Financial-Data. Sie müssen encrypted und access-controlled sein.
Encryption-at-Rest:
# Encrypt Backup mit GPG
mongodump --uri="$MONGO_URI" --archive | gpg --encrypt --recipient backup@company.com > /backup/mongodb-$(date +%Y%m%d).archive.gpg
# Decrypt und Restore
gpg --decrypt /backup/mongodb-20240120.archive.gpg | mongorestore --archiveOder Filesystem-Level-Encryption:
Wenn Backups auf encrypted Volumes gespeichert werden (LUKS, AWS-EBS-Encryption), sind sie automatisch encrypted.
Access-Control:
Backup-Files sollten restricted Permissions haben:
chmod 600 /backup/mongodb-*.bson # Only Owner kann read/writeFür Cloud-Storage (S3, GCS):
# AWS S3 mit Server-Side-Encryption
aws s3 cp /backup/mongodb-20240120 s3://company-backups/mongodb/ --recursive --sse AES256
# Mit IAM-Policy: Nur Backup-Role kann accessEin Disaster-Recovery-Plan ist ein dokumentierter Workflow für Restore-Scenarios. Es sollte schritt-für-schritt Instructions enthalten, sodass jeder im Team (nicht nur der DBA) einen Restore durchführen kann.
Example-DR-Playbook:
# MongoDB Disaster Recovery Playbook
## Scenario 1: Accidental Data-Deletion
**Detection:** User reports missing data, confirmed in database
**Steps:**
1. Determine deletion time (check application logs)
2. Identify latest good backup before deletion
3. Provision temporary restore-server
4. Restore backup to temp-server
5. Export affected data from temp-server
6. Import data to production
7. Validate data integrity
8. Notify stakeholders
**Estimated Time:** 2 hours
**Required Access:** Production DB, Backup-Storage, Temp-Server
## Scenario 2: Database Corruption
**Detection:** MongoDB errors, failed queries, crashes
**Steps:**
1. Stop application traffic to database
2. Assess corruption extent (run db.repairDatabase())
3. If repair fails: Restore from latest backup
4. For replica-set: Restore to one member, re-sync others
5. Validate restored data
6. Resume application traffic
7. Conduct post-mortem
**Estimated Time:** 4 hours
**Required Access:** Production DB, Backup-Storage
## Scenario 3: Complete Datacenter Loss
**Detection:** All servers unreachable
**Steps:**
1. Activate DR-site or provision new infrastructure
2. Restore from off-site backups (S3, GCS)
3. Restore config-servers first (for sharded clusters)
4. Restore shards/replica-sets
5. Update DNS to point to new infrastructure
6. Resume application traffic
7. Monitor for issues
**Estimated Time:** 8-12 hours
**Required Access:** DR-site, Off-site backups, DNS-managementDieses Playbook sollte regelmäßig geübt werden – etwa via Disaster-Recovery-Drills, wo man einen simulated Disaster durchspielt.
Die folgende Tabelle fasst Backup-Methods zusammen:
| Method | Speed | Size | Granularity | Consistency | Best-For |
|---|---|---|---|---|---|
| mongodump | Slow | Small | Collection-Level | Eventually | Small DBs, Dev/Test |
| Filesystem-Snapshot | Fast | Full-Volume | Database-Level | Point-in-Time | Large DBs, Production |
| Replica-Backup | Medium | Variable | Database-Level | Point-in-Time | Replica-Sets |
| Oplog-Backup | Continuous | Incremental | Point-in-Time | Exact | Enterprise, Zero-RPO |
| Cloud-Managed (Atlas) | Automated | Efficient | Point-in-Time | Exact | Managed-MongoDB |
Backups sind nicht glamorous – sie sind boring, repetitive, und hoffentlich niemals genutzt. Aber wenn der unthinkable-Disaster passiert, sind sie die einzige Rettung. Die Best-Practice ist Defense-in-Depth: Multiple-Backup-Methods (etwa Filesystem-Snapshots täglich + Oplog-Continuous), off-site-Backups (separate Datacenter oder Cloud-Region), encrypted-Backups, regelmäßiges Testing, documented-DR-Playbooks, und Practiced-Drills. Mit systematischem Backup-Management wird Data-Loss von catastrophic zu recoverable – nicht perfekt vermeidbar, aber manageable und boundable. Die Frage ist nicht “Werden wir jemals Backups brauchen” sondern “Wann werden wir Backups brauchen, und werden sie funktionieren”. Mit richtigem Backup-Design ist die Antwort: “Ja, sie werden funktionieren.”