www_site/docs/OPERATIONS.md
flym 99976ef77f docs: record configured offsite NAS backup (rsync over SSH)
Offsite backup to the Synology NAS (103.40.14.100:52200) is now configured:
pg_dump of business+CMS DBs (keep 7 per series) plus rsync of the audio dir,
encrypted over SSH with key auth, on a daily 03:00 systemd timer. Document the
destination, transport, script, timer, and restore-from-NAS procedure; mark the
backup-location item resolved (retention/threshold/owner still pending).
2026-09-10 15:24:04 +08:00

85 lines
5.8 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.

# 运维方案OPERATIONS
日期2026-09-10 · 版本 `8657f44`
范围:音频容量/保留/清理/备份/恢复、数据库备份/恢复、Worker 与额度对账、告警。**本轮不擅自删除任何既有音频。**
## 1. 音频存储现状
- 位置:`/home/flym/kaotings-audio`,布局 `{user_id}/{task_id}.wav`(私有本地目录,非对象存储)。
- 元数据:`audio_files``storage_key`、`mime_type`、`size_bytes`、`checksum`、`status`、`expires_at`)。
- 写入:成功结算时先写文件、再登记 `audio_files`(含 SHA256
- 读取:回放/下载按 `storage_key` 取文件;文件缺失返回 404优雅降级
## 2. 备份(已配置异地备份)
- 本机暂存:`/home/flym/backups/`(仅存放 `.dump`)。
- 异地备份目标:**Synology NAS** `103.40.14.100`Synology DSM账号 `kts_bak`,落盘 `/var/services/homes/kts_bak/backup/kaotings/``db/` + `audio/`),可用容量约 92 GiB。
- 传输方式:**rsync over SSH**(端口 `52200`**加密**),密钥认证(`/root/.ssh/id_ed25519_ktsbak`,公钥已加入 NAS `kts_bak``authorized_keys`)。**不使用** 公网明文 rsync 守护端口 `50873`
- 脚本:`/usr/local/sbin/kaotings-backup.sh`root 运行):
1. `pg_dump --format=custom` 业务库(`/etc/kaotings/api.env` → `DATABASE_URL`)与 CMS 库(`/etc/kaotings/cms.env` → `DATABASE_URI`)。
2. 每库保留最近 **7** 份(按序列独立轮转)。
3. `rsync -a --delete` 增量镜像 `db/``audio/``AUDIO_STORAGE_DIR`)到 NAS。
- 定时systemd `kaotings-backup.timer`,每日 **03:00**`Persistent=true``RandomizedDelaySec=30min`)触发 `kaotings-backup.service`
- 验证:首份备份已落盘(业务库 54K、CMS 48K、音频 22 文件 4.8M`pg_restore --list` 确认归档可恢复。
| 对象 | 工具 | 本机 | 异地NAS |
| --- | --- | --- | --- |
| 业务库 `kaotings` | `pg_dump --format=custom` | `/home/flym/backups/kaotings_<ts>.dump` | `…/backup/kaotings/db/` |
| CMS 库 `kaotings_cms` | `pg_dump --format=custom` | `/home/flym/backups/kaotings_cms_<ts>.dump` | `…/backup/kaotings/db/` |
| 音频目录 | `rsync -a --delete` | `/home/flym/kaotings-audio/` | `…/backup/kaotings/audio/` |
> 仍待用户确认:音频保留期、磁盘告警阈值、是否启用按 `expires_at` 的定时清理(见 §5。备份保留份数当前=7可按需调整脚本 `KEEP`。
## 3. 容量 / 保留 / 清理(需用户决定的参数集中列出)
| 参数 | 当前值 | 需用户决定 |
| --- | --- | --- |
| 音频保留期 `AUDIO_RETENTION_SECONDS` | 7 天(默认) | 是(产品/隐私/存储预算) |
| 磁盘容量上限 / 告警阈值 | 根盘约 48 GiB 可用,无上限告警 | 是(阈值 + 通知方式) |
| 保留期清理策略 | 未启用定时清理(仅启动时清孤儿) | 是(是否按 `expires_at` 定时删除) |
| 原始文本保留期 | 存于 `tts_tasks.text` | 是(产品/隐私) |
| 备份保留份数 / 周期 | 已配置:每库 7 份 · 每日 03:00 · 异地 NAS | 否(可调脚本 `KEEP` 与 timer |
- 清理安全边界:
- 启动时 `cleanup_orphan_audio` 仅删除“**无** `available` 记录且 mtime>1h”的孤儿文件。
- 保留期清理在参数确认并实现后启用;**在此之前不删除任何既有音频**。
- 告警:磁盘使用率超阈值、`audio_files` 与磁盘文件数量长期不一致、Worker 长期无 `queued` 消化。
## 4. 恢复(含隔离演练结果)
### 4.1 流程
1. 停止写入(可选,视 RPO`systemctl stop kaotings-api`。
2. 建空库 → `pg_restore --clean --if-exists` 业务库 / CMS 库。
3. 音频:从 NAS 异地备份 `rsync`/`scp` 回 `/home/flym/kaotings-audio`(源:`…/backup/kaotings/audio/`)。
4. 校验:行数、音频文件↔`audio_files` 关联、`checksum`、额度↔流水一致(见 §4.2 校验 SQL
5. `systemctl start kaotings-api``/healthz` 复核。
### 4.2 校验(隔离演练已执行)
- 业务库行数源=恢复users 35 / quota 34 / tasks 28 / audio 26 / usage 61 / grants 10。
- 额度↔流水:`used` 与 `consume`、`reserved` 与 `reserve-consume-release` 均 0 不符。
- 音频:磁盘 22 文件全部被 `available` 引用(无孤儿)。
- **发现**4 条 `status=available` 且任务 `succeeded``audio_files` 行在磁盘无文件(既有不一致,回放 404 降级)。待调查根因(见 §6
### 4.3 Worker 重启 / 额度对账
- 单 Workersystemd 单进程),原子领取(`FOR UPDATE SKIP LOCKED`+ 5 分钟租约 + 过期 `running` 回收(`WORKER_LEASE_EXPIRED`,释放冻结)。
- 对账:`GET /admin/usage/summary` 汇总 `quota_accounts``usage_records` 口径;`GET /admin/tts/tasks` 查结算状态consumed/released/pending
- 不变式(每账户恒成立):`limit_snapshot + adjustment - used - reserved >= 0`(由 Phase 5 异常矩阵 S3/S4 保证)。
## 5. 待用户确认清单(集中)
1. 音频保留期(`AUDIO_RETENTION_SECONDS`)。
2. 磁盘容量上限与告警阈值、通知方式。
3. 是否启用按 `expires_at` 的定时保留期清理。
4. 原始文本保留期。
5. 备份:异地 NAS 已配置(`103.40.14.100`,每日 03:00每库 7 份);**剩余待确认**:保留份数/周期是否调整、备份责任人。
6. 上游 HTTPS/加密端点、允许来源网段、凭据轮换(见 `DEPLOYMENT.md` §4
## 6. 待调查 / 未闭环项(不标为完成)
- **4 条 `available` 音频行无对应文件**:既有 DB/文件系统不一致,待定位根因(文件被外部删除 or 写入路径异常);恢复流程本身通过。
- **上游公网 HTTP**:上线阻断,待加密 + 来源限制 + 外部复测(`DEPLOYMENT.md` §4
- **音频容量/保留/清理参数**待用户确认§5