备份与维护
PicFast 在管理后台内置了维护仪表盘,可查看磁盘健康度、数据库统计和 pHash 覆盖率,并提供一键清理工具。对于深层操作,则提供 picfast maintenance 命令行,用于一致性巡检、备份导出、恢复以及缩略图修复。
管理后台仪表盘
在管理后台导航至维护页面,监控系统健康状态并执行常规清理:
- 磁盘健康: 实时查看本地存储后端的容量、使用量和 inode 统计。
- 数据库统计: 概览记录数、表大小及 pHash 计算覆盖率。
- 清理工具: 识别并删除存储后端中的未关联对象(即没有数据库记录的孤儿文件)。
- 风险审计: 检查可能存在安全或运维风险的系统配置。
CLI: 执行前注意
- 使用与线上实例一致的配置(
config.yaml/ 环境变量),以便 CLI 能连接 PostgreSQL 与各存储后端。 - 下文 Compose 示例中的
<service>须替换为你在docker-compose.yml里为 PicFast 定义的实际服务名(示例仓库常用app,你的环境可能不同)。 - 体量较大时建议在维护窗口执行:
doctor与完整备份会大量读取对象。
命令形式
docker compose exec <service> picfast maintenance <子命令> [参数] 使用 picfast maintenance --help 与各子命令的 --help 查看参数(如 --json、--all、--pg-dump-container 等)。
子命令
| 子命令 | 作用 |
|---|---|
doctor | 只读巡检:数据库记录、对象存储与缩略图是否一致。 |
backup | 导出 PostgreSQL 自定义格式 dump,并可按需把对象一并打入归档。 |
inspect | 校验备份包内的 manifest.json 与校验和。 |
restore | 默认仅预检;加 --apply 才写入。目标库非空时需显式 --force。 |
repair-thumbnails | 根据源对象重建缺失缩略图(默认演练,--apply 才写入)。 |
recalc-phash | 为所有符合条件的图片重新计算缺失的感知哈希 (pHash)。 |
推荐顺序
- 巡检:
picfast maintenance doctor --all --batch-size 500 - 备份:
picfast maintenance backup --output /app/data/backups/picfast-backup.tar.gz(路径请按实际卷挂载调整) - 校验归档:
picfast maintenance inspect /app/data/backups/picfast-backup.tar.gz - 恢复(在目标环境、预检通过后):
picfast maintenance restore … --apply;仅在确认要覆盖非空库时使用--force。
PostgreSQL 客户端工具
若宿主机未安装 pg_dump / pg_restore,可将 CLI 指向已有 Postgres 容器(如 --pg-dump-container、--pg-restore-container),详见 backup 与 restore 的 --help。
自动备份
利用宿主机 cron 定时执行备份——无需修改任何代码。两种策略搭配使用:
| 类型 | 频率 | 范围 | 保留 |
|---|---|---|---|
| db-only | 每小时 | 仅 PostgreSQL 元数据 | 最近 48 份 |
| full | 每天 | 数据库 + 图片文件 | 最近 7 份 |
第一步:数据库备份脚本
创建 /opt/picfast/backup-db.sh:
#!/bin/bash
set -euo pipefail
CONTAINER="${1:-picfast-db}"
BACKUP_DIR="${2:-/opt/picfast/data/backups}"
DB_USER="${3:-picfast}"
DB_NAME="${4:-picfast}"
RETENTION="${5:-48}"
TIMESTAMP=$(date +%Y%m%d-%H%M)
OUTPUT="$BACKUP_DIR/db-$TIMESTAMP.dump.gz"
mkdir -p "$BACKUP_DIR"
docker exec "$CONTAINER" pg_dump --format=custom -U "$DB_USER" -d "$DB_NAME" \
| gzip > "$OUTPUT"
echo "备份完成: $OUTPUT ($(du -h "$OUTPUT" | cut -f1))"
# 清理过期备份
ls -1t "$BACKUP_DIR"/db-*.dump.gz 2>/dev/null \
| tail -n +$((RETENTION + 1)) \
| xargs -r rm -v chmod +x /opt/picfast/backup-db.sh 第二步:全量备份脚本
创建 /opt/picfast/backup-full.sh:
#!/bin/bash
set -euo pipefail
PROJECT_DIR="${1:-/opt/picfast}"
COMPOSE_FILE="${2:-$PROJECT_DIR/docker/docker-compose.yml}"
RETENTION="${3:-7}"
TIMESTAMP=$(date +%Y%m%d)
OUTPUT="$PROJECT_DIR/data/backups/full-$TIMESTAMP.tar.gz"
cd "$PROJECT_DIR"
docker compose -f "$COMPOSE_FILE" run --rm app \
picfast maintenance backup \
--output "/app/data/backups/full-$TIMESTAMP.tar.gz"
echo "全量备份完成: $OUTPUT"
ls -1t "$PROJECT_DIR"/data/backups/full-*.tar.gz \
| tail -n +$((RETENTION + 1)) \
| xargs -r rm -v chmod +x /opt/picfast/backup-full.sh 第三步:配置定时任务
crontab -e # PicFast 自动备份
0 * * * * /opt/picfast/backup-db.sh picfast-db /opt/picfast/data/backups picfast picfast 48
0 3 * * * /opt/picfast/backup-full.sh /opt/picfast /opt/picfast/docker/docker-compose.yml 7 第四步(可选):异地同步
用 rclone 将备份和静态文件推送到远程存储:
30 3 * * * rclone sync /opt/picfast/data/backups remote:bucket/picfast-backups
30 3 * * * rclone sync /opt/picfast/data/uploads remote:bucket/picfast-uploads
30 3 * * * rclone sync /opt/picfast/data/thumbnails remote:bucket/picfast-thumbnails 从备份恢复
# 仅数据库
gunzip -c /opt/picfast/data/backups/db-20260728-1400.dump.gz | \
docker exec -i picfast-db pg_restore --clean --if-exists --no-owner -U picfast -d picfast
# 完整恢复
docker compose -f docker/docker-compose.yml run --rm app \
picfast maintenance restore /app/data/backups/full-20260728.tar.gz --apply --force 归档格式与完整说明
Manifest 字段、objects.jsonl 与校验账本的职责、兼容性约定及更多实现细节见 PicFast 仓库文档:
docs/maintenance.md。