Backup and Recovery
MongoDB Backup Strategies
mongodump/mongorestore
# Full database backup
mongodump --uri="mongodb://localhost:27017" --out=/backup/$(date +%Y%m%d)
# Specific database
mongodump --db=myapp --out=/backup/myapp
# Specific collection
mongodump --db=myapp --collection=users --out=/backup/users
# Compressed backup
mongodump --archive=/backup/myapp.gz --gzip --db=myapp
# Restore
mongorestore --archive=/backup/myapp.gz --gzip
# Restore to different database
mongorestore --archive=/backup/myapp.gz --gzip --nsFrom='myapp.*' --nsTo='myapp_restored.*'Replica Set Backup
// Backup from secondary (no impact on primary)
const { MongoClient } = require('mongodb');
const client = new MongoClient('mongodb://secondary:27017', {
readPreference: 'secondary'
});
// Or use mongodump from secondary
// mongodump --host=secondary:27017 --out=/backupPoint-in-Time Recovery
# Enable oplog
mongod --replSet rs0 --oplogSize 1024
# Backup with oplog
mongodump --oplog --out=/backup/$(date +%Y%m%d)
# Restore to specific point in time
mongorestore --oplogReplay --oplogLimit="1609459200:1" /backup/20240101Automated Backups
const cron = require('node-cron');
const { exec } = require('child_process');
const { promisify } = require('util');
const execPromise = promisify(exec);
class BackupService {
constructor() {
// Run daily at 2 AM
cron.schedule('0 2 * * *', () => this.performBackup());
}
async performBackup() {
const timestamp = new Date().toISOString().split('T')[0];
const backupPath = `/backup/${timestamp}`;
try {
// Create backup
await execPromise(`mongodump --out=${backupPath} --gzip`);
// Upload to S3
await this.uploadToS3(backupPath);
// Clean old backups (keep last 30 days)
await this.cleanOldBackups(30);
console.log(`Backup completed: ${timestamp}`);
} catch (error) {
console.error('Backup failed:', error);
await this.notifyAdmin(error);
}
}
async uploadToS3(backupPath) {
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const fs = require('fs');
const files = fs.readdirSync(backupPath);
for (const file of files) {
const fileContent = fs.readFileSync(`${backupPath}/${file}`);
await s3.putObject({
Bucket: 'my-backups',
Key: `mongodb/${backupPath}/${file}`,
Body: fileContent
}).promise();
}
}
async cleanOldBackups(daysToKeep) {
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - daysToKeep);
const backups = fs.readdirSync('/backup');
for (const backup of backups) {
const backupDate = new Date(backup);
if (backupDate < cutoffDate) {
await execPromise(`rm -rf /backup/${backup}`);
}
}
}
}Cassandra Backup
Snapshot Backup
# Create snapshot
nodetool snapshot -t snapshot-$(date +%Y%m%d) myapp
# Snapshots stored in data directory
# /var/lib/cassandra/data/myapp/users-*/snapshots/
# Copy snapshots to backup location
cp -r /var/lib/cassandra/data/myapp/*/snapshots/snapshot-20240101 /backup/
# Clear old snapshots
nodetool clearsnapshot -t snapshot-20240101Incremental Backup
# Enable incremental backups
nodetool enablebackup
# Backups stored in backups directory
# /var/lib/cassandra/data/myapp/users-*/backups/
# Restore from incremental backup
# 1. Stop Cassandra
# 2. Clear data directory
# 3. Copy snapshot
# 4. Copy incremental backups
# 5. Start CassandraRedis Backup
RDB Snapshots
# redis.conf
save 900 1 # Save if 1 key changed in 900 seconds
save 300 10 # Save if 10 keys changed in 300 seconds
save 60 10000 # Save if 10000 keys changed in 60 seconds
# Manual snapshot
redis-cli SAVE
# Background snapshot
redis-cli BGSAVE
# Copy RDB file
cp /var/lib/redis/dump.rdb /backup/dump-$(date +%Y%m%d).rdbAOF Persistence
# redis.conf
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
# Rewrite AOF
redis-cli BGREWRITEAOF
# Backup AOF
cp /var/lib/redis/appendonly.aof /backup/aof-$(date +%Y%m%d).aofRedis Backup Script
const redis = require('redis');
const { exec } = require('child_process');
const { promisify } = require('util');
const execPromise = promisify(exec);
class RedisBackupService {
async performBackup() {
const client = redis.createClient();
await client.connect();
try {
// Trigger background save
await client.bgSave();
// Wait for save to complete
await this.waitForSave(client);
// Copy RDB file
const timestamp = new Date().toISOString().split('T')[0];
await execPromise(`cp /var/lib/redis/dump.rdb /backup/dump-${timestamp}.rdb`);
console.log('Redis backup completed');
} finally {
await client.quit();
}
}
async waitForSave(client) {
let saving = true;
while (saving) {
const info = await client.info('persistence');
saving = info.includes('rdb_bgsave_in_progress:1');
if (saving) {
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
}
}DynamoDB Backup
On-Demand Backup
const { DynamoDBClient, CreateBackupCommand } = require('@aws-sdk/client-dynamodb');
const client = new DynamoDBClient({ region: 'us-east-1' });
async function createBackup(tableName) {
const timestamp = new Date().toISOString();
const command = new CreateBackupCommand({
TableName: tableName,
BackupName: `${tableName}-${timestamp}`
});
const response = await client.send(command);
console.log('Backup created:', response.BackupDetails.BackupArn);
}Point-in-Time Recovery
const { UpdateContinuousBackupsCommand, RestoreTableToPointInTimeCommand } = require('@aws-sdk/client-dynamodb');
// Enable PITR
async function enablePITR(tableName) {
const command = new UpdateContinuousBackupsCommand({
TableName: tableName,
PointInTimeRecoverySpecification: {
PointInTimeRecoveryEnabled: true
}
});
await client.send(command);
}
// Restore to point in time
async function restoreToPointInTime(sourceTable, targetTable, restoreDateTime) {
const command = new RestoreTableToPointInTimeCommand({
SourceTableName: sourceTable,
TargetTableName: targetTable,
RestoreDateTime: restoreDateTime
});
await client.send(command);
}Disaster Recovery
Recovery Time Objective (RTO)
const recoveryStrategies = {
hotStandby: {
rto: '< 1 minute',
cost: 'High',
setup: 'Active-active replication'
},
warmStandby: {
rto: '< 1 hour',
cost: 'Medium',
setup: 'Replica set with automated failover'
},
coldStandby: {
rto: '< 24 hours',
cost: 'Low',
setup: 'Daily backups, manual restore'
}
};Disaster Recovery Plan
class DisasterRecoveryService {
async executeRecoveryPlan() {
console.log('Starting disaster recovery...');
// 1. Assess damage
const status = await this.assessDatabaseStatus();
if (status.corrupted) {
// 2. Stop application
await this.stopApplication();
// 3. Restore from backup
await this.restoreFromBackup();
// 4. Verify data integrity
await this.verifyDataIntegrity();
// 5. Start application
await this.startApplication();
// 6. Monitor
await this.monitorRecovery();
}
}
async restoreFromBackup() {
// Get latest backup
const latestBackup = await this.getLatestBackup();
// Restore
await execPromise(`mongorestore --archive=${latestBackup} --gzip --drop`);
// Apply oplog if available
if (this.hasOplog(latestBackup)) {
await execPromise(`mongorestore --oplogReplay ${latestBackup}`);
}
}
async verifyDataIntegrity() {
// Check document counts
const collections = await db.listCollections().toArray();
for (const collection of collections) {
const count = await db.collection(collection.name).countDocuments();
console.log(`${collection.name}: ${count} documents`);
}
// Verify indexes
for (const collection of collections) {
const indexes = await db.collection(collection.name).indexes();
console.log(`${collection.name} indexes:`, indexes.length);
}
}
}Backup Testing
class BackupTestingService {
async testBackupRestore() {
console.log('Testing backup restore...');
// 1. Create test database
const testDb = 'myapp_restore_test';
// 2. Restore backup to test database
await execPromise(`mongorestore --archive=/backup/latest.gz --gzip --nsFrom='myapp.*' --nsTo='${testDb}.*'`);
// 3. Verify data
const client = new MongoClient('mongodb://localhost:27017');
await client.connect();
const db = client.db(testDb);
const collections = await db.listCollections().toArray();
for (const collection of collections) {
const count = await db.collection(collection.name).countDocuments();
console.log(`${collection.name}: ${count} documents`);
}
// 4. Clean up test database
await db.dropDatabase();
await client.close();
console.log('Backup restore test completed');
}
// Schedule monthly restore tests
scheduleRestoreTests() {
cron.schedule('0 3 1 * *', () => this.testBackupRestore());
}
}.NET Backup Service
using MongoDB.Driver;
using System.Diagnostics;
public class BackupService
{
public async Task CreateBackup(string databaseName)
{
var timestamp = DateTime.UtcNow.ToString("yyyyMMdd-HHmmss");
var backupPath = $"/backup/{databaseName}-{timestamp}";
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "mongodump",
Arguments = $"--db={databaseName} --out={backupPath} --gzip",
RedirectStandardOutput = true,
UseShellExecute = false
}
};
process.Start();
await process.WaitForExitAsync();
if (process.ExitCode == 0)
{
Console.WriteLine($"Backup created: {backupPath}");
await UploadToCloud(backupPath);
}
else
{
throw new Exception("Backup failed");
}
}
public async Task RestoreBackup(string backupPath, string databaseName)
{
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "mongorestore",
Arguments = $"--archive={backupPath} --gzip --db={databaseName} --drop",
RedirectStandardOutput = true,
UseShellExecute = false
}
};
process.Start();
await process.WaitForExitAsync();
if (process.ExitCode == 0)
{
Console.WriteLine("Restore completed");
}
else
{
throw new Exception("Restore failed");
}
}
}Backup Best Practices
const backupBestPractices = [
'Automate backups with cron jobs',
'Test restore procedures regularly',
'Store backups in multiple locations',
'Encrypt backups',
'Monitor backup success/failure',
'Document recovery procedures',
'Set retention policies',
'Use incremental backups for large datasets',
'Backup from secondary replicas',
'Verify backup integrity',
'Keep backups off-site',
'Practice disaster recovery drills'
];Backup Monitoring
class BackupMonitor {
async checkBackupHealth() {
const latestBackup = await this.getLatestBackup();
const backupAge = Date.now() - latestBackup.timestamp;
// Alert if backup older than 25 hours
if (backupAge > 25 * 60 * 60 * 1000) {
await this.sendAlert('Backup is overdue');
}
// Verify backup size
const backupSize = await this.getBackupSize(latestBackup.path);
if (backupSize < this.minExpectedSize) {
await this.sendAlert('Backup size is suspiciously small');
}
// Test restore
if (this.shouldTestRestore()) {
await this.testBackupRestore();
}
}
}Interview Tips
- Explain strategies: mongodump, snapshots, PITR
- Show automation: Cron jobs, scheduled backups
- Demonstrate restore: Recovery procedures
- Discuss testing: Regular restore tests
- Mention DR: Disaster recovery planning
- Show examples: MongoDB, Cassandra, Redis, DynamoDB
Summary
Implement automated backups with mongodump, snapshots, or cloud-native solutions. Use replica sets to backup from secondaries. Enable point-in-time recovery for critical data. Store backups in multiple locations with encryption. Test restore procedures regularly. Document disaster recovery plans. Monitor backup health and age. Set retention policies. Practice recovery drills. Use incremental backups for large datasets. Essential for data protection and business continuity.
Test Your Knowledge
Take a quick quiz to test your understanding of this topic.