feat(backup): mysqldump 定时备份/恢复演练/健康检查脚本与手册
- scripts/backup_full.sh:容器内 mysqldump --single-transaction,gzip 落盘 db/backups/,保留 30 天;凭据 source docker/.env 不硬编码;实测备份成功 - scripts/restore_drill.sh:恢复到临时库 payroll_drill_* 并逐表核对行数 (16 张关键表),默认不 DROP、--drop-exec 才删——绝不覆盖生产库; 实测 16 表全 ✓。规避嵌套 shell 吞反引号(mysqladmin create/drop、 双引号包裹表名) - scripts/health_check.sh:六项检查(容器健康×2/磁盘水位/备份新鲜度/ Redis 探活/24h 登录失败阈值),PASS/WARN/FAIL 报告,退出码供监控; Redis 密码经宿主机 .env 验证(容器内无该环境变量),实测六项全 PASS - docs/备份恢复手册.md:备份/演练/生产恢复七步/定时 schtasks 两则, db/backups/ 已入 .gitignore Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
1 parent
927592b472
commit
b5e27810fd
4 files changed
+321
No files matched your search
@@ -0,0 +1,70 @@
|
||||
# 备份恢复手册(⑨ 备份恢复与运维检查)
|
||||
|
||||
> 用户强调「这个备份恢复很重要」。**备份不演练 = 没有备份**——本手册的一页纸目标:任何运维/开发拿到都能完成「备份 → 恢复到临时库核对 → 删临时库」全链路。
|
||||
|
||||
## 一、备份(每日一次,建议凌晨低峰)
|
||||
|
||||
```bash
|
||||
# 项目根目录执行
|
||||
bash scripts/backup_full.sh
|
||||
```
|
||||
|
||||
- 产物:`db/backups/payroll_YYYYMMDD_HHMMSS.sql.gz`(gzip 压缩)
|
||||
- 保留策略:自动清理 30 天前的旧备份
|
||||
- 凭据:从 `docker/.env` 读取(不入脚本、不入版本库)
|
||||
|
||||
**Windows 定时任务**(任务计划程序 / `schtasks`):
|
||||
|
||||
```cmd
|
||||
:: 每日 02:30 备份(经 Git Bash)
|
||||
schtasks /create /tn "ys-payroll-backup" /tr "\"C:\Program Files\Git\bin\bash.exe\" -lc \"bash scripts/backup_full.sh\"" /sc daily /st 02:30 /ru SYSTEM
|
||||
```
|
||||
|
||||
## 二、恢复演练(备份后顺手跑一次,验证备份真能用)
|
||||
|
||||
```bash
|
||||
bash scripts/restore_drill.sh # 恢复到临时库 + 行数核对,临时库默认保留
|
||||
bash scripts/restore_drill.sh --drop-exec # 核对通过后再加此参数删除临时库
|
||||
```
|
||||
|
||||
- **绝不直接覆盖生产库**——演练恢复到独立临时库 `payroll_drill_<时间戳>`
|
||||
- 行数对比覆盖 16 张关键表(users/roles/param_*/business*/personnel/products/customers/shipments*/receipts/approval_*/system_settings)
|
||||
- 全部 ✓ 即备份可恢复;出现 ✗ 时临时库保留供排查
|
||||
|
||||
## 三、生产恢复(真出事了,七步)
|
||||
|
||||
> ⚠️ 生产恢复是**高危操作**:先把容器停了再恢复,避免写冲突。下面假设恢复到**全新空数据卷**(最干净路径)。
|
||||
|
||||
1. **停容器保卷**:`docker compose -f docker/docker-compose.dev.yml down`
|
||||
2. **删旧卷(谨慎!确认要全量重来才执行)**:`docker volume rm ys-payroll_mysql-dev-data`
|
||||
- 若只想恢复到某个时间点**且不丢其它数据**,改用「恢复到临时库 → mysqldump 单表导出 → 手工回灌」的细粒度路径,勿整体覆盖。
|
||||
3. **起空库**:`docker compose -f docker/docker-compose.dev.yml up -d`(首启自动跑 `db/init/init-dev.sql` 建表 + 种子)
|
||||
4. **选一份备份**:`ls -t db/backups/payroll_*.sql.gz | head`
|
||||
5. **导入该备份**:
|
||||
```bash
|
||||
gunzip -c db/backups/payroll_XXXXXXXX_XXXXXX.sql.gz | \
|
||||
docker exec -i ys-mysql-dev sh -c 'mysql -uroot -p"$MYSQL_ROOT_PASSWORD" payroll'
|
||||
```
|
||||
6. **核对行数**:再跑一次 `bash scripts/restore_drill.sh`(此时源库=刚恢复的库,应全 ✓)
|
||||
7. **重启后端**:`cd backend && uv run uvicorn app.main:app --reload --port 8000`,登录抽查几个页面确认数据回来
|
||||
|
||||
## 四、运维健康检查(每日一次)
|
||||
|
||||
```bash
|
||||
bash scripts/health_check.sh
|
||||
```
|
||||
|
||||
六项检查:容器健康 ×2 / 磁盘水位(80% 阈值)/ 备份新鲜度(24h 内)/ Redis 探活 / 24h 登录失败次数(暴力破解预警)。任一项 WARN/FAIL 时退出码非零,方便监控采集。
|
||||
|
||||
**Windows 定时**:
|
||||
|
||||
```cmd
|
||||
:: 每日 08:50 检查(上班前出报告)
|
||||
schtasks /create /tn "ys-payroll-health" /tr "\"C:\Program Files\Git\bin\bash.exe\" -lc \"bash scripts/health_check.sh >> db/backups/health.log 2>&1\"" /sc daily /st 08:50 /ru SYSTEM
|
||||
```
|
||||
|
||||
## 五、注意事项
|
||||
|
||||
- 备份含**全部业务数据与参数种子**,属敏感文件——`db/backups/` 已加入 `.gitignore`,**不要**把它提交到版本库
|
||||
- 恢复演练产生的 `payroll_drill_*` 库会占磁盘,核对完及时 `--drop-exec` 清理
|
||||
- 备份脚本与恢复脚本都只依赖 Docker(无需宿主机装 MySQL 客户端)
|
||||
Reference in new issue
Block a user