签入版本
This commit is contained in:
@@ -0,0 +1,235 @@
|
||||
# 备份与恢复
|
||||
|
||||
## 概述
|
||||
|
||||
定期备份是防止数据丢失的最后防线。本文介绍 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.fastapi_user
|
||||
UNION ALL
|
||||
SELECT 'article', COUNT(*) FROM djangoadmin_restore.fastapi_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 天备份。关键要点:备份文件异地存储、定期恢复演练验证完整性、监控备份任务执行状态。
|
||||
Reference in New Issue
Block a user