Moved the backup out of the NAS home dir to /volume1/NetBackup/kaotings per request. Synology restricts rsync-over-SSH to registered shared folders and scp/sftp yields root-owned files that the backup account cannot rotate, so the backup now uses tar over SSH (kts_bak-owned, rotatable, encrypted, key auth). Document the transport rationale and the DSM shared-folder upgrade path for incremental rsync.
6.6 KiB
6.6 KiB
运维方案(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,账号kts_bak,落盘/volume1/NetBackup/kaotings/(db/+audio/,不在 home 下),可用容量约 92 GiB。 - 传输方式:tar over SSH(端口
52200,加密),密钥认证(/root/.ssh/id_ed25519_ktsbak,公钥已加入 NASkts_bak的authorized_keys)。不使用 公网明文 rsync 守护端口50873。- 为何不用 rsync:Synology 限制 rsync-over-SSH 仅能写入已注册的共享文件夹;
/volume1/NetBackup是普通目录(非 DSM 共享文件夹),rsync 会报0 bytes received。而scp/sftp 虽能写入,但会生成 root 属主文件,kts_bak无法轮转删除。tar over SSH(ssh exec) 生成的文件属主为kts_bak,可正常轮转。 - 升级路径:若在 DSM 中将
NetBackup建为共享文件夹(控制面板→共享文件夹,授予kts_bak读写),即可改回rsync -a --delete获得增量传输。
- 为何不用 rsync:Synology 限制 rsync-over-SSH 仅能写入已注册的共享文件夹;
- 脚本:
/usr/local/sbin/kaotings-backup.sh(root 运行):pg_dump --format=custom业务库(/etc/kaotings/api.env→DATABASE_URL)与 CMS 库(/etc/kaotings/cms.env→DATABASE_URI)。- 每库本机保留最近 7 份(按序列独立轮转)。
tarover SSH 传db/与audio/(AUDIO_STORAGE_DIR)到 NAS;再在远端按序列保留 7 份(ssh exec,可删除kts_bak属主文件)。
- 定时:systemd
kaotings-backup.timer,每日 03:00(Persistent=true,RandomizedDelaySec=30min)触发kaotings-backup.service。 - 验证:备份已落盘
/volume1/NetBackup/kaotings(db 5+6 份、音频 22 文件,共 5.4M,属主kts_bak);pg_restore --list确认归档可恢复。
| 对象 | 工具 | 本机 | 异地(NAS /volume1/NetBackup/kaotings) |
|---|---|---|---|
业务库 kaotings |
pg_dump --format=custom + tar |
/home/flym/backups/kaotings_<ts>.dump |
…/kaotings/db/ |
CMS 库 kaotings_cms |
pg_dump --format=custom + tar |
/home/flym/backups/kaotings_cms_<ts>.dump |
…/kaotings/db/ |
| 音频目录 | tar over SSH | /home/flym/kaotings-audio/ |
…/kaotings/audio/ |
仍待用户确认:音频保留期、磁盘告警阈值、是否启用按
expires_at的定时清理(见 §5);备份保留份数当前=7(可调脚本KEEP)。如希望增量传输,请在 DSM 将NetBackup建为共享文件夹(见上“升级路径”)。
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 流程
- 停止写入(可选,视 RPO):
systemctl stop kaotings-api。 - 建空库 →
pg_restore --clean --if-exists业务库 / CMS 库。 - 音频:从 NAS 用
tarover SSH 拉回/home/flym/kaotings-audio(源:/volume1/NetBackup/kaotings/audio/)。 - 校验:行数、音频文件↔
audio_files关联、checksum、额度↔流水一致(见 §4.2 校验 SQL)。 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 重启 / 额度对账
- 单 Worker(systemd 单进程),原子领取(
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. 待用户确认清单(集中)
- 音频保留期(
AUDIO_RETENTION_SECONDS)。 - 磁盘容量上限与告警阈值、通知方式。
- 是否启用按
expires_at的定时保留期清理。 - 原始文本保留期。
- 备份:异地 NAS 已配置(
103.40.14.100,每日 03:00,每库 7 份);剩余待确认:保留份数/周期是否调整、备份责任人。 - 上游 HTTPS/加密端点、允许来源网段、凭据轮换(见
DEPLOYMENT.md§4)。
6. 待调查 / 未闭环项(不标为完成)
- 4 条
available音频行无对应文件:既有 DB/文件系统不一致,待定位根因(文件被外部删除 or 写入路径异常);恢复流程本身通过。 - 上游公网 HTTP:上线阻断,待加密 + 来源限制 + 外部复测(
DEPLOYMENT.md§4)。 - 音频容量/保留/清理参数:待用户确认(§5)。