# 运维方案(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. 备份 | 对象 | 工具 | 位置 | 说明 | | --- | --- | --- | --- | | 业务库 `kaotings` | `pg_dump --format=custom` | `/home/flym/backups/kaotings_.dump` | 含用户/额度/任务/音频元数据/流水 | | CMS 库 `kaotings_cms` | `infra/scripts/backup-cms-db.sh`(root) | `/home/flym/backups/kaotings_cms_.dump` | 独立库/账号 | | 音频目录 | `tar`/`rsync` 到隔离位置 | 待指定 | 与库备份分开存放 | > 备份位置、保留期、异地/异机与责任人:**待用户确认**(见 §5)。 ## 3. 容量 / 保留 / 清理(需用户决定的参数集中列出) | 参数 | 当前值 | 需用户决定 | | --- | --- | --- | | 音频保留期 `AUDIO_RETENTION_SECONDS` | 7 天(默认) | 是(产品/隐私/存储预算) | | 磁盘容量上限 / 告警阈值 | 根盘约 48 GiB 可用,无上限告警 | 是(阈值 + 通知方式) | | 保留期清理策略 | 未启用定时清理(仅启动时清孤儿) | 是(是否按 `expires_at` 定时删除) | | 原始文本保留期 | 存于 `tts_tasks.text` | 是(产品/隐私) | | 备份保留份数 / 周期 | 待确认 | 是(运维负责人) | - 清理安全边界: - 启动时 `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. 音频:从隔离备份拷贝到 `/home/flym/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 重启 / 额度对账 - 单 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. 待用户确认清单(集中) 1. 音频保留期(`AUDIO_RETENTION_SECONDS`)。 2. 磁盘容量上限与告警阈值、通知方式。 3. 是否启用按 `expires_at` 的定时保留期清理。 4. 原始文本保留期。 5. 备份位置(异地/异机)、保留份数与周期、责任人。 6. 上游 HTTPS/加密端点、允许来源网段、凭据轮换(见 `DEPLOYMENT.md` §4)。 ## 6. 待调查 / 未闭环项(不标为完成) - **4 条 `available` 音频行无对应文件**:既有 DB/文件系统不一致,待定位根因(文件被外部删除 or 写入路径异常);恢复流程本身通过。 - **上游公网 HTTP**:上线阻断,待加密 + 来源限制 + 外部复测(`DEPLOYMENT.md` §4)。 - **音频容量/保留/清理参数**:待用户确认(§5)。