Files
djangoadmin-wiki/DjangoAdmin_Flask_NaiveVue/zh/volume6/backup.md
T
2026-09-12 23:12:15 +08:00

236 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 备份与恢复
## 概述
定期备份是防止数据丢失的最后防线。本文介绍 MySQL 数据库备份、Redis 数据备份、上传文件备份的方案,以及自动化备份调度和恢复操作。
:::tip 备份策略 3-2-1 原则
- **3** 份数据副本(1 份生产 + 2 份备份)
- **2** 种不同存储介质(如本地磁盘 + 远程存储)
- **1** 份异地备份(防机房级灾难)
:::
## MySQL 数据库备份
### 全量备份
```bash
# 使用 mysqldump 备份单个数据库
mysqldump -h 127.0.0.1 -u root -p --single-transaction \
--routines --triggers --events \
djangoadmin_prod > backup_$(date +%Y%m%d_%H%M%S).sql
# 压缩备份
mysqldump -h 127.0.0.1 -u root -p --single-transaction \
djangoadmin_prod | gzip > backup_$(date +%Y%m%d_%H%M%S).sql.gz
```
:::tip --single-transaction 作用
`--single-transaction` 参数确保 InnoDB 表的备份一致性,不锁表,不影响线上服务。
:::
### 增量备份
基于 MySQL binlog 实现增量备份:
```bash
# 查看当前 binlog 位置
mysql -u root -p -e "SHOW MASTER STATUS;"
# 备份 binlog
mysqlbinlog --start-datetime="2026-09-05 00:00:00" \
mysql-bin.000001 > binlog_incremental.sql
```
:::tip binlog 配置
确保 MySQL 配置中启用了 binlog:
```ini
[mysqld]
server-id = 1
log-bin = mysql-bin
binlog-format = ROW
expire_logs_days = 7
```
:::
### 仅备份表结构
```bash
# 仅备份结构(不含数据)
mysqldump -h 127.0.0.1 -u root -p --no-data \
djangoadmin_prod > schema_$(date +%Y%m%d).sql
```
## Redis 数据备份
### RDB 快照
```bash
# 手动触发 RDB 快照
redis-cli BGSAVE
# 查看最后一次快照时间
redis-cli LASTSAVE
# 复制 RDB 文件
cp /var/lib/redis/dump.rdb /data/backup/redis_$(date +%Y%m%d).rdb
```
### AOF 持久化
```bash
# redis.conf 配置
appendonly yes
appendfsync everysec
# 备份 AOF 文件
cp /var/lib/redis/appendonly.aof /data/backup/redis_$(date +%Y%m%d).aof
```
:::tip Redis 备份建议
Redis 用于缓存和 token 黑名单,数据可从数据库重建。建议使用 RDB 快照即可,AOF 可选。
:::
## 上传文件备份
```bash
# 打包上传目录
tar -czf uploads_$(date +%Y%m%d).tar.gz /data/apps/uploads/
# 使用 rsync 增量同步到远程
rsync -avz --delete /data/apps/uploads/ backup@10.0.2.100:/data/backup/uploads/
```
## 自动化备份
### 备份脚本
创建 `/data/scripts/backup.sh`:
```bash
#!/bin/bash
# 备份目录
BACKUP_DIR="/data/backup"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7
# 创建备份目录
mkdir -p ${BACKUP_DIR}/{mysql,redis,uploads}
# MySQL 备份
mysqldump -h 127.0.0.1 -u djangoadmin -p'<密码>' \
--single-transaction djangoadmin_prod | gzip > \
${BACKUP_DIR}/mysql/backup_${DATE}.sql.gz
# Redis 备份
redis-cli BGSAVE
sleep 5
cp /var/lib/redis/dump.rdb ${BACKUP_DIR}/redis/redis_${DATE}.rdb
# 上传文件备份
tar -czf ${BACKUP_DIR}/uploads/uploads_${DATE}.tar.gz /data/apps/uploads/
# 清理过期备份
find ${BACKUP_DIR} -type f -mtime +${RETENTION_DAYS} -delete
echo "[$(date)] Backup completed" >> /var/log/backup.log
```
### Crontab 配置
```bash
# 编辑定时任务
crontab -e
# 每天凌晨 2 点执行备份
0 2 * * * /bin/bash /data/scripts/backup.sh >> /var/log/backup.log 2>&1
# 每周日凌晨 3 点执行全量备份
0 3 * * 0 /bin/bash /data/scripts/backup_full.sh >> /var/log/backup.log 2>&1
```
:::tip Crontab 说明
```
分 时 日 月 周 命令
0 2 * * * /bin/bash /data/scripts/backup.sh
│ │ │ │ │
│ │ │ │ └── 星期几 (0-7, 0和7都是周日)
│ │ │ └──── 月份 (1-12)
│ │ └─────── 日 (1-31)
│ └────────── 时 (0-23)
└───────────── 分 (0-59)
```
:::
## 数据恢复
### MySQL 恢复
```bash
# 从 SQL 文件恢复
mysql -h 127.0.0.1 -u root -p djangoadmin_prod < backup_20260905.sql
# 从压缩文件恢复
gunzip < backup_20260905.sql.gz | mysql -h 127.0.0.1 -u root -p djangoadmin_prod
```
### Redis 恢复
```bash
# 停止 Redis
redis-cli SHUTDOWN NOSAVE
# 替换 RDB 文件
cp /data/backup/redis/redis_20260905.rdb /var/lib/redis/dump.rdb
# 启动 Redis
redis-server /etc/redis/redis.conf
```
### 上传文件恢复
```bash
# 解压恢复
tar -xzf uploads_20260905.tar.gz -C /
```
## 恢复演练
:::warning 重要
定期进行恢复演练,验证备份文件的完整性和可用性。建议每季度至少演练一次。
:::
```bash
# 恢复演练步骤
# 1. 在测试环境创建空库
mysql -u root -p -e "CREATE DATABASE djangoadmin_restore;"
# 2. 恢复备份
mysql -u root -p djangoadmin_restore < backup_20260905.sql
# 3. 验证数据完整性
mysql -u root -p -e "
SELECT 'user' AS tbl, COUNT(*) AS cnt FROM djangoadmin_restore.flask_user
UNION ALL
SELECT 'article', COUNT(*) FROM djangoadmin_restore.flask_article;
"
# 4. 清理测试库
mysql -u root -p -e "DROP DATABASE djangoadmin_restore;"
```
## 备份监控
```bash
# 检查备份文件是否存在且非空
find /data/backup/mysql -name "*.sql.gz" -mtime -1 -size +0 | wc -l
# 返回 0 则告警
# 检查备份文件大小
ls -lh /data/backup/mysql/backup_$(date +%Y%m%d)*.sql.gz
```
## 总结
备份方案覆盖 MySQL(mysqldump 全量 + binlog 增量)、Redis(RDB 快照)、上传文件(tar 打包 + rsync 同步)。通过 Crontab 实现自动化调度,保留最近 7 天备份。关键要点:备份文件异地存储、定期恢复演练验证完整性、监控备份任务执行状态。