database-backups
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDatabase Backups
数据库备份
Implement comprehensive, automated database backup strategies with tested recovery procedures.
实施全面的自动化数据库备份策略,并搭配经过测试的恢复流程。
When to Use
适用场景
- You are deploying a new database and need a backup plan from day one.
- You need to automate nightly or hourly backups for PostgreSQL, MySQL, or MongoDB.
- You want to ship backups to S3-compatible object storage with retention policies.
- You are building or verifying disaster recovery runbooks.
- 您正在部署新数据库,需要从第一天就制定备份计划。
- 您需要为PostgreSQL、MySQL或MongoDB实现夜间或每小时自动备份。
- 您希望将备份存储到兼容S3的对象存储中,并配置保留策略。
- 您正在构建或验证灾难恢复手册。
Prerequisites
前提条件
- Database client tools installed (,
pg_dump,mysqldump).mongodump - AWS CLI or for remote storage.
restic - or systemd timers for scheduling.
cron - An S3 bucket (or S3-compatible endpoint) for offsite backups.
- 已安装数据库客户端工具(、
pg_dump、mysqldump)。mongodump - 用于远程存储的AWS CLI或。
restic - 用于调度任务的或systemd定时器。
cron - 用于异地备份的S3存储桶(或兼容S3的端点)。
Backup Types
备份类型
| Type | Description | Frequency | Use Case |
|---|---|---|---|
| Full | Complete database copy | Weekly | Baseline for restores |
| Incremental | Changes since last backup | Daily | Reduce storage and time |
| Transaction log / WAL | Continuous log shipping | Continuous | Point-in-time recovery (PITR) |
| Snapshot | Storage-level snapshot (EBS, ZFS) | Daily | Fast full restores |
| 类型 | 描述 | 频率 | 适用场景 |
|---|---|---|---|
| 全量备份 | 完整的数据库副本 | 每周 | 作为恢复的基线 |
| 增量备份 | 自上次备份以来的变更数据 | 每日 | 减少存储占用和备份时间 |
| 事务日志/WAL | 持续日志传输 | 持续 | 时点恢复(PITR) |
| 快照 | 存储级快照(EBS、ZFS) | 每日 | 快速全量恢复 |
PostgreSQL Backups
PostgreSQL备份
Logical Backup with pg_dump
使用pg_dump进行逻辑备份
bash
#!/bin/bashbash
#!/bin/bashpg_backup.sh — PostgreSQL logical backup
pg_backup.sh — PostgreSQL logical backup
set -euo pipefail
DB_NAME="mydb"
DB_USER="backup_user"
DB_HOST="localhost"
BACKUP_DIR="/backups/postgres"
DATE=$(date +%Y%m%d_%H%M%S)
FILENAME="${BACKUP_DIR}/${DB_NAME}_${DATE}.dump"
mkdir -p "$BACKUP_DIR"
set -euo pipefail
DB_NAME="mydb"
DB_USER="backup_user"
DB_HOST="localhost"
BACKUP_DIR="/backups/postgres"
DATE=$(date +%Y%m%d_%H%M%S)
FILENAME="${BACKUP_DIR}/${DB_NAME}_${DATE}.dump"
mkdir -p "$BACKUP_DIR"
Custom compressed format (recommended for selective restore)
Custom compressed format (recommended for selective restore)
pg_dump -h "$DB_HOST" -U "$DB_USER" -Fc -Z6 "$DB_NAME" > "$FILENAME"
echo "[$(date)] PostgreSQL backup complete: $FILENAME ($(du -h "$FILENAME" | cut -f1))"
undefinedpg_dump -h "$DB_HOST" -U "$DB_USER" -Fc -Z6 "$DB_NAME" > "$FILENAME"
echo "[$(date)] PostgreSQL backup complete: $FILENAME ($(du -h "$FILENAME" | cut -f1))"
undefinedPhysical Backup with pg_basebackup
使用pg_basebackup进行物理备份
bash
#!/bin/bashbash
#!/bin/bashpg_basebackup.sh — PostgreSQL physical backup for PITR
pg_basebackup.sh — PostgreSQL physical backup for PITR
set -euo pipefail
BACKUP_DIR="/backups/postgres/base_$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
pg_basebackup
-h localhost
-U replicator
-D "$BACKUP_DIR"
--wal-method=stream
--checkpoint=fast
--progress
--verbose
-h localhost
-U replicator
-D "$BACKUP_DIR"
--wal-method=stream
--checkpoint=fast
--progress
--verbose
echo "[$(date)] Base backup complete: $BACKUP_DIR"
undefinedset -euo pipefail
BACKUP_DIR="/backups/postgres/base_$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
pg_basebackup
-h localhost
-U replicator
-D "$BACKUP_DIR"
--wal-method=stream
--checkpoint=fast
--progress
--verbose
-h localhost
-U replicator
-D "$BACKUP_DIR"
--wal-method=stream
--checkpoint=fast
--progress
--verbose
echo "[$(date)] Base backup complete: $BACKUP_DIR"
undefinedPostgreSQL Restore
PostgreSQL恢复
bash
undefinedbash
undefinedRestore from custom-format dump
从自定义格式备份恢复
pg_restore -h localhost -U myapp -d mydb --clean --if-exists /backups/postgres/mydb_20250115_020000.dump
pg_restore -h localhost -U myapp -d mydb --clean --if-exists /backups/postgres/mydb_20250115_020000.dump
Restore a single table
恢复单个表
pg_restore -h localhost -U myapp -d mydb -t orders /backups/postgres/mydb_20250115_020000.dump
pg_restore -h localhost -U myapp -d mydb -t orders /backups/postgres/mydb_20250115_020000.dump
Restore from plain SQL
从纯SQL文件恢复
psql -h localhost -U myapp -d mydb < /backups/postgres/mydb_20250115.sql
undefinedpsql -h localhost -U myapp -d mydb < /backups/postgres/mydb_20250115.sql
undefinedMySQL Backups
MySQL备份
Logical Backup with mysqldump
使用mysqldump进行逻辑备份
bash
#!/bin/bashbash
#!/bin/bashmysql_backup.sh — MySQL logical backup
mysql_backup.sh — MySQL logical backup
set -euo pipefail
DB_NAME="mydb"
DB_USER="backup_user"
DB_PASS="${MYSQL_BACKUP_PASSWORD}"
BACKUP_DIR="/backups/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
FILENAME="${BACKUP_DIR}/${DB_NAME}_${DATE}.sql.gz"
mkdir -p "$BACKUP_DIR"
mysqldump -u "$DB_USER" -p"$DB_PASS"
--single-transaction
--routines
--triggers
--events
"$DB_NAME" | gzip > "$FILENAME"
--single-transaction
--routines
--triggers
--events
"$DB_NAME" | gzip > "$FILENAME"
echo "[$(date)] MySQL backup complete: $FILENAME ($(du -h "$FILENAME" | cut -f1))"
undefinedset -euo pipefail
DB_NAME="mydb"
DB_USER="backup_user"
DB_PASS="${MYSQL_BACKUP_PASSWORD}"
BACKUP_DIR="/backups/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
FILENAME="${BACKUP_DIR}/${DB_NAME}_${DATE}.sql.gz"
mkdir -p "$BACKUP_DIR"
mysqldump -u "$DB_USER" -p"$DB_PASS"
--single-transaction
--routines
--triggers
--events
"$DB_NAME" | gzip > "$FILENAME"
--single-transaction
--routines
--triggers
--events
"$DB_NAME" | gzip > "$FILENAME"
echo "[$(date)] MySQL backup complete: $FILENAME ($(du -h "$FILENAME" | cut -f1))"
undefinedPhysical Backup with Percona XtraBackup
使用Percona XtraBackup进行物理备份
bash
#!/bin/bashbash
#!/bin/bashxtrabackup.sh — MySQL physical backup
xtrabackup.sh — MySQL physical backup
set -euo pipefail
BACKUP_DIR="/backups/mysql/full_$(date +%Y%m%d)"
xtrabackup --backup
--user=backup_user
--password="${MYSQL_BACKUP_PASSWORD}"
--target-dir="$BACKUP_DIR"
--user=backup_user
--password="${MYSQL_BACKUP_PASSWORD}"
--target-dir="$BACKUP_DIR"
xtrabackup --prepare --target-dir="$BACKUP_DIR"
echo "[$(date)] XtraBackup complete: $BACKUP_DIR"
undefinedset -euo pipefail
BACKUP_DIR="/backups/mysql/full_$(date +%Y%m%d)"
xtrabackup --backup
--user=backup_user
--password="${MYSQL_BACKUP_PASSWORD}"
--target-dir="$BACKUP_DIR"
--user=backup_user
--password="${MYSQL_BACKUP_PASSWORD}"
--target-dir="$BACKUP_DIR"
xtrabackup --prepare --target-dir="$BACKUP_DIR"
echo "[$(date)] XtraBackup complete: $BACKUP_DIR"
undefinedMySQL Restore
MySQL恢复
bash
undefinedbash
undefinedRestore from compressed mysqldump
从压缩的mysqldump备份恢复
gunzip < /backups/mysql/mydb_20250115_020000.sql.gz | mysql -u root -p mydb
gunzip < /backups/mysql/mydb_20250115_020000.sql.gz | mysql -u root -p mydb
Restore from XtraBackup
从XtraBackup备份恢复
sudo systemctl stop mysql
sudo rm -rf /var/lib/mysql/*
xtrabackup --move-back --target-dir=/backups/mysql/full_20250115
sudo chown -R mysql:mysql /var/lib/mysql
sudo systemctl start mysql
undefinedsudo systemctl stop mysql
sudo rm -rf /var/lib/mysql/*
xtrabackup --move-back --target-dir=/backups/mysql/full_20250115
sudo chown -R mysql:mysql /var/lib/mysql
sudo systemctl start mysql
undefinedMongoDB Backups
MongoDB备份
Logical Backup with mongodump
使用mongodump进行逻辑备份
bash
#!/bin/bashbash
#!/bin/bashmongo_backup.sh — MongoDB backup
mongo_backup.sh — MongoDB backup
set -euo pipefail
MONGO_URI="mongodb://backup_user:${MONGO_BACKUP_PASSWORD}@localhost:27017"
BACKUP_DIR="/backups/mongodb"
DATE=$(date +%Y%m%d_%H%M%S)
TARGET="${BACKUP_DIR}/${DATE}"
mkdir -p "$BACKUP_DIR"
set -euo pipefail
MONGO_URI="mongodb://backup_user:${MONGO_BACKUP_PASSWORD}@localhost:27017"
BACKUP_DIR="/backups/mongodb"
DATE=$(date +%Y%m%d_%H%M%S)
TARGET="${BACKUP_DIR}/${DATE}"
mkdir -p "$BACKUP_DIR"
Full backup with compression
Full backup with compression
mongodump --uri="$MONGO_URI" --gzip --out="$TARGET"
echo "[$(date)] MongoDB backup complete: $TARGET"
undefinedmongodump --uri="$MONGO_URI" --gzip --out="$TARGET"
echo "[$(date)] MongoDB backup complete: $TARGET"
undefinedMongoDB Restore
MongoDB恢复
bash
undefinedbash
undefinedRestore all databases
恢复所有数据库
mongorestore --uri="mongodb://admin:secret@localhost:27017"
--gzip --drop /backups/mongodb/20250115_020000/
--gzip --drop /backups/mongodb/20250115_020000/
mongorestore --uri="mongodb://admin:secret@localhost:27017"
--gzip --drop /backups/mongodb/20250115_020000/
--gzip --drop /backups/mongodb/20250115_020000/
Restore a single database
恢复单个数据库
mongorestore --uri="mongodb://admin:secret@localhost:27017"
--gzip --drop --db mydb /backups/mongodb/20250115_020000/mydb/
--gzip --drop --db mydb /backups/mongodb/20250115_020000/mydb/
mongorestore --uri="mongodb://admin:secret@localhost:27017"
--gzip --drop --db mydb /backups/mongodb/20250115_020000/mydb/
--gzip --drop --db mydb /backups/mongodb/20250115_020000/mydb/
Restore a single collection
恢复单个集合
mongorestore --uri="mongodb://admin:secret@localhost:27017"
--gzip --drop --db mydb --collection users
/backups/mongodb/20250115_020000/mydb/users.bson.gz
--gzip --drop --db mydb --collection users
/backups/mongodb/20250115_020000/mydb/users.bson.gz
undefinedmongorestore --uri="mongodb://admin:secret@localhost:27017"
--gzip --drop --db mydb --collection users
/backups/mongodb/20250115_020000/mydb/users.bson.gz
--gzip --drop --db mydb --collection users
/backups/mongodb/20250115_020000/mydb/users.bson.gz
undefinedUpload to S3
上传至S3
bash
#!/bin/bashbash
#!/bin/bashs3_upload.sh — Upload backups to S3
s3_upload.sh — Upload backups to S3
set -euo pipefail
S3_BUCKET="s3://my-backups"
BACKUP_DIR="/backups"
DATE=$(date +%Y%m%d)
set -euo pipefail
S3_BUCKET="s3://my-backups"
BACKUP_DIR="/backups"
DATE=$(date +%Y%m%d)
Upload PostgreSQL backup
Upload PostgreSQL backup
aws s3 cp "${BACKUP_DIR}/postgres/" "${S3_BUCKET}/postgres/${DATE}/"
--recursive --storage-class STANDARD_IA
--sse AES256
--recursive --storage-class STANDARD_IA
--sse AES256
aws s3 cp "${BACKUP_DIR}/postgres/" "${S3_BUCKET}/postgres/${DATE}/"
--recursive --storage-class STANDARD_IA
--sse AES256
--recursive --storage-class STANDARD_IA
--sse AES256
Upload MySQL backup
Upload MySQL backup
aws s3 cp "${BACKUP_DIR}/mysql/" "${S3_BUCKET}/mysql/${DATE}/"
--recursive --storage-class STANDARD_IA
--sse AES256
--recursive --storage-class STANDARD_IA
--sse AES256
aws s3 cp "${BACKUP_DIR}/mysql/" "${S3_BUCKET}/mysql/${DATE}/"
--recursive --storage-class STANDARD_IA
--sse AES256
--recursive --storage-class STANDARD_IA
--sse AES256
Upload MongoDB backup
Upload MongoDB backup
aws s3 cp "${BACKUP_DIR}/mongodb/" "${S3_BUCKET}/mongodb/${DATE}/"
--recursive --storage-class STANDARD_IA
--sse AES256
--recursive --storage-class STANDARD_IA
--sse AES256
echo "[$(date)] S3 upload complete for ${DATE}"
undefinedaws s3 cp "${BACKUP_DIR}/mongodb/" "${S3_BUCKET}/mongodb/${DATE}/"
--recursive --storage-class STANDARD_IA
--sse AES256
--recursive --storage-class STANDARD_IA
--sse AES256
echo "[$(date)] S3 upload complete for ${DATE}"
undefinedS3 Lifecycle Policy for Retention
S3生命周期保留策略
json
{
"Rules": [
{
"ID": "BackupRetention",
"Status": "Enabled",
"Filter": { "Prefix": "" },
"Transitions": [
{ "Days": 30, "StorageClass": "GLACIER" }
],
"Expiration": { "Days": 365 }
}
]
}bash
aws s3api put-bucket-lifecycle-configuration \
--bucket my-backups \
--lifecycle-configuration file://lifecycle.jsonjson
{
"Rules": [
{
"ID": "BackupRetention",
"Status": "Enabled",
"Filter": { "Prefix": "" },
"Transitions": [
{ "Days": 30, "StorageClass": "GLACIER" }
],
"Expiration": { "Days": 365 }
}
]
}bash
aws s3api put-bucket-lifecycle-configuration \
--bucket my-backups \
--lifecycle-configuration file://lifecycle.jsonRestic Backup (Encrypted, Deduplicated)
Restic备份(加密、去重)
bash
undefinedbash
undefinedInitialize a restic repository on S3
Initialize a restic repository on S3
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="..."
export RESTIC_PASSWORD="strong_encryption_password"
export RESTIC_REPOSITORY="s3:s3.amazonaws.com/my-backups-restic"
restic init
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="..."
export RESTIC_PASSWORD="strong_encryption_password"
export RESTIC_REPOSITORY="s3:s3.amazonaws.com/my-backups-restic"
restic init
Backup the local backup directory
Backup the local backup directory
restic backup /backups/postgres /backups/mysql /backups/mongodb
restic backup /backups/postgres /backups/mysql /backups/mongodb
List snapshots
List snapshots
restic snapshots
restic snapshots
Prune old snapshots — keep 7 daily, 4 weekly, 6 monthly
Prune old snapshots — keep 7 daily, 4 weekly, 6 monthly
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
Restore a snapshot
Restore a snapshot
restic restore latest --target /restore/
undefinedrestic restore latest --target /restore/
undefinedCron Schedules
Cron调度计划
bash
undefinedbash
undefined/etc/cron.d/db-backups
/etc/cron.d/db-backups
PostgreSQL: nightly at 02:00
PostgreSQL: 每日02:00执行
0 2 * * * backup /opt/scripts/pg_backup.sh >> /var/log/backup-pg.log 2>&1
0 2 * * * backup /opt/scripts/pg_backup.sh >> /var/log/backup-pg.log 2>&1
MySQL: nightly at 02:30
MySQL: 每日02:30执行
30 2 * * * backup /opt/scripts/mysql_backup.sh >> /var/log/backup-mysql.log 2>&1
30 2 * * * backup /opt/scripts/mysql_backup.sh >> /var/log/backup-mysql.log 2>&1
MongoDB: nightly at 03:00
MongoDB: 每日03:00执行
0 3 * * * backup /opt/scripts/mongo_backup.sh >> /var/log/backup-mongo.log 2>&1
0 3 * * * backup /opt/scripts/mongo_backup.sh >> /var/log/backup-mongo.log 2>&1
Upload to S3: daily at 04:00
上传至S3: 每日04:00执行
0 4 * * * backup /opt/scripts/s3_upload.sh >> /var/log/backup-s3.log 2>&1
0 4 * * * backup /opt/scripts/s3_upload.sh >> /var/log/backup-s3.log 2>&1
Local cleanup: keep 7 days of local backups
本地清理: 保留7天本地备份
0 5 * * * backup find /backups -type f -mtime +7 -delete >> /var/log/backup-cleanup.log 2>&1
0 5 * * * backup find /backups -type f -mtime +7 -delete >> /var/log/backup-cleanup.log 2>&1
Restic prune: weekly on Sunday at 06:00
Restic清理: 每周日06:00执行
0 6 * * 0 backup /opt/scripts/restic_prune.sh >> /var/log/backup-restic.log 2>&1
undefined0 6 * * 0 backup /opt/scripts/restic_prune.sh >> /var/log/backup-restic.log 2>&1
undefinedAutomated Recovery Testing
自动化恢复测试
bash
#!/bin/bashbash
#!/bin/bashverify_backup.sh — weekly restore test
verify_backup.sh — weekly restore test
set -euo pipefail
BACKUP_FILE=$(ls -t /backups/postgres/mydb_*.dump | head -1)
echo "[$(date)] Starting backup verification with $BACKUP_FILE"
set -euo pipefail
BACKUP_FILE=$(ls -t /backups/postgres/mydb_*.dump | head -1)
echo "[$(date)] Starting backup verification with $BACKUP_FILE"
Spin up a temporary PostgreSQL container
启动临时PostgreSQL容器
docker run -d --name pg-restore-test
-e POSTGRES_USER=testuser
-e POSTGRES_PASSWORD=testpass
-e POSTGRES_DB=testdb
postgres:16-alpine
-e POSTGRES_USER=testuser
-e POSTGRES_PASSWORD=testpass
-e POSTGRES_DB=testdb
postgres:16-alpine
docker run -d --name pg-restore-test
-e POSTGRES_USER=testuser
-e POSTGRES_PASSWORD=testpass
-e POSTGRES_DB=testdb
postgres:16-alpine
-e POSTGRES_USER=testuser
-e POSTGRES_PASSWORD=testpass
-e POSTGRES_DB=testdb
postgres:16-alpine
Wait for container to be ready
等待容器就绪
sleep 5
until docker exec pg-restore-test pg_isready -U testuser; do
sleep 2
done
sleep 5
until docker exec pg-restore-test pg_isready -U testuser; do
sleep 2
done
Copy backup into container and restore
将备份文件复制到容器并恢复
docker cp "$BACKUP_FILE" pg-restore-test:/tmp/backup.dump
docker exec pg-restore-test pg_restore -U testuser -d testdb --clean --if-exists /tmp/backup.dump
docker cp "$BACKUP_FILE" pg-restore-test:/tmp/backup.dump
docker exec pg-restore-test pg_restore -U testuser -d testdb --clean --if-exists /tmp/backup.dump
Run verification queries
执行验证查询
USERS_COUNT=$(docker exec pg-restore-test psql -U testuser -d testdb -tAc "SELECT COUNT() FROM users;")
ORDERS_COUNT=$(docker exec pg-restore-test psql -U testuser -d testdb -tAc "SELECT COUNT() FROM orders;")
echo "[$(date)] Verification: users=$USERS_COUNT, orders=$ORDERS_COUNT"
USERS_COUNT=$(docker exec pg-restore-test psql -U testuser -d testdb -tAc "SELECT COUNT() FROM users;")
ORDERS_COUNT=$(docker exec pg-restore-test psql -U testuser -d testdb -tAc "SELECT COUNT() FROM orders;")
echo "[$(date)] Verification: users=$USERS_COUNT, orders=$ORDERS_COUNT"
Cleanup
清理资源
docker rm -f pg-restore-test
docker rm -f pg-restore-test
Alert on failure
验证失败时发送告警
if [ "$USERS_COUNT" -lt 1 ]; then
echo "ALERT: Backup verification failed — users table is empty" >&2
exit 1
fi
echo "[$(date)] Backup verification PASSED"
undefinedif [ "$USERS_COUNT" -lt 1 ]; then
echo "ALERT: Backup verification failed — users table is empty" >&2
exit 1
fi
echo "[$(date)] Backup verification PASSED"
undefinedUnified Backup Script
统一备份脚本
bash
#!/bin/bashbash
#!/bin/bashbackup_all.sh — unified backup orchestrator
backup_all.sh — unified backup orchestrator
set -euo pipefail
LOG="/var/log/backup-all.log"
ALERT_EMAIL="ops@example.com"
ERRORS=0
log() { echo "[$(date '+%F %T')] $*" | tee -a "$LOG"; }
run_backup() {
local name="$1" script="$2"
log "Starting $name backup..."
if bash "$script" >> "$LOG" 2>&1; then
log "$name backup succeeded."
else
log "ERROR: $name backup FAILED."
ERRORS=$((ERRORS + 1))
fi
}
run_backup "PostgreSQL" /opt/scripts/pg_backup.sh
run_backup "MySQL" /opt/scripts/mysql_backup.sh
run_backup "MongoDB" /opt/scripts/mongo_backup.sh
run_backup "S3 Upload" /opt/scripts/s3_upload.sh
if [ "$ERRORS" -gt 0 ]; then
log "Backup run completed with $ERRORS error(s). Sending alert."
mail -s "BACKUP ALERT: $ERRORS failure(s)" "$ALERT_EMAIL" < "$LOG"
exit 1
fi
log "All backups completed successfully."
undefinedset -euo pipefail
LOG="/var/log/backup-all.log"
ALERT_EMAIL="ops@example.com"
ERRORS=0
log() { echo "[$(date '+%F %T')] $*" | tee -a "$LOG"; }
run_backup() {
local name="$1" script="$2"
log "Starting $name backup..."
if bash "$script" >> "$LOG" 2>&1; then
log "$name backup succeeded."
else
log "ERROR: $name backup FAILED."
ERRORS=$((ERRORS + 1))
fi
}
run_backup "PostgreSQL" /opt/scripts/pg_backup.sh
run_backup "MySQL" /opt/scripts/mysql_backup.sh
run_backup "MongoDB" /opt/scripts/mongo_backup.sh
run_backup "S3 Upload" /opt/scripts/s3_upload.sh
if [ "$ERRORS" -gt 0 ]; then
log "Backup run completed with $ERRORS error(s). Sending alert."
mail -s "BACKUP ALERT: $ERRORS failure(s)" "$ALERT_EMAIL" < "$LOG"
exit 1
fi
log "All backups completed successfully."
undefinedBest Practices
最佳实践
- 3-2-1 Rule: Keep 3 copies of data, on 2 different media types, with 1 offsite.
- Encrypt backups at rest: Use (built-in encryption), AWS SSE, or
restic.gpg - Test restores regularly: A backup that has never been restored is not a backup.
- Monitor backup jobs: Alert immediately on any failure; do not rely on silent cron jobs.
- Document RTOs and RPOs: Define Recovery Time Objective and Recovery Point Objective for each database.
- Version your backup scripts: Store them in Git alongside your infrastructure code.
- Use : For MySQL and PostgreSQL logical backups to get a consistent snapshot.
--single-transaction - Separate backup credentials: Use a dedicated read-only database user for backups.
- 3-2-1原则: 保留3份数据副本,存储在2种不同介质上,其中1份异地存储。
- 静态备份加密: 使用(内置加密)、AWS SSE或
restic对备份加密。gpg - 定期测试恢复: 从未被恢复过的备份不能算作有效备份。
- 监控备份任务: 备份失败时立即告警,不要依赖静默运行的cron任务。
- 定义RTO和RPO: 为每个数据库定义恢复时间目标(Recovery Time Objective)和恢复点目标(Recovery Point Objective)。
- 版本控制备份脚本: 将备份脚本与基础设施代码一起存储在Git中。
- 使用: 在MySQL和PostgreSQL逻辑备份中使用该参数以获取一致的快照。
--single-transaction - 独立备份凭证: 使用专用的只读数据库用户进行备份操作。
Troubleshooting
故障排除
| Symptom | Likely Cause | Fix |
|---|---|---|
| Backup connection competes with app pool | Schedule during low traffic; increase |
| Table lock contention | Use |
| Reading from secondary under load | Use |
| S3 upload fails with timeout | Large file over slow connection | Use |
| Restic prune takes hours | Too many snapshots accumulated | Run |
| Restore fails with "role does not exist" | Backup includes role-dependent objects | Create roles first or use |
| 症状 | 可能原因 | 解决方法 |
|---|---|---|
| 备份连接与应用连接池竞争 | 低峰期调度备份;为备份用户增加5个 |
| 表锁竞争 | 使用 |
| 从节点负载过高 | 使用 |
| S3上传因超时失败 | 大文件通过慢速网络传输 | 使用 |
| Restic清理耗时数小时 | 快照累积过多 | 更频繁地运行 |
| 恢复时提示“role does not exist” | 备份包含依赖角色的对象 | 先创建角色,或在恢复时使用 |
Related Skills
相关技能
- postgresql - PostgreSQL administration and pg_dump details
- mysql - MySQL administration and mysqldump details
- mongodb - MongoDB administration and mongodump details
- redis - Redis RDB/AOF persistence and backup
- postgresql - PostgreSQL管理及pg_dump详细说明
- mysql - MySQL管理及mysqldump详细说明
- mongodb - MongoDB管理及mongodump详细说明
- redis - Redis RDB/AOF持久化及备份