Files
knowledge-governance/scripts/backup_layout.sh
T
姚章浩 b32755b35f feat(backup): 备份目录契约 + 导入前留档覆盖 ES 层
- scripts/backup_layout.sh:定义 $KB_BACKUP_ROOT/{target-kb-snapshots,rds-logical,es-snapshots,logs}
  与 /etc/knowledge-governance/backup.env,任意主机跑同一份(测试云主机 → 未来生产云主机)
- scripts/es_kb_export.py:只读 scroll 导出目标库 ES 文档(gzip JSONL,_id/_source,可按 _id 重建)
- scripts/target_kb_snapshot.sh:留档改为 PG 行 + ES 文档两层;PULL_ES 默认 0(692 MB / 家用上行 19m40s,
  留在目标主机,清单记 location=cloud:<host>:<path>);挂载源与落点统一走 KB_BACKUP_ROOT
- scripts/logical-backup.sh:自管整库逻辑备份(pg_dump -Fd -j4 -Z6,按天轮转)
- internal/releasesnapshot:门禁要求 PG 与 ES 两层齐备(ES 计数 >0);云侧留档核声明与哈希、
  声明本地却缺失则 fail-closed;新增 3 条用例(共 10)
- cmd/guardcheck:用真实产物复核门禁判断
- docs:PRODUCTION_BACKUP_RECOVERY.md 重写(契约/RDS 控制台/恢复路径/边界);P6 同步留档语义
2026-10-09 12:19:15 +08:00

66 lines
2.9 KiB
Bash
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.
#!/usr/bin/env bash
# 备份/快照的**目录契约**:任何一台扮演"目标库所在主机"的机器(现在的测试云主机、
# 未来的生产云主机、以及本地演练机)都跑这一份,得到同一套落点。
#
# 为什么要统一:发布前的留档、整库逻辑备份、ES 快照仓、发布包归档分属不同脚本,
# 一旦各自选路径,换主机时就要逐个改脚本,且"发布前快照"的门禁会指到错的地方。
#
# 目录布局($KB_BACKUP_ROOT 底下):
# target-kb-snapshots/<UTC>-<kb8>/ 发布/导入前的行级留档(PG 8 表 + ES 文档,小、随发布留)
# rds-logical/<UTC>/ 整库逻辑备份(pg_dump -Fd 目录格式,按天轮转)
# es-snapshots/ Elasticsearch 共享仓库 kb_backup 的宿主目录
# logs/ 上述脚本的运行日志
#
# 用法(在目标主机上):
# bash backup_layout.sh # 建目录 + 落配置,打印现状
# KB_BACKUP_ROOT=/data/kb-backups bash backup_layout.sh
# bash backup_layout.sh --print # 只打印契约,不动磁盘
#
# 产出配置:/etc/knowledge-governance/backup.env(KB_BACKUP_ROOT=…),供各脚本 source。
set -euo pipefail
KB_BACKUP_ROOT="${KB_BACKUP_ROOT:-/srv/kb-backups}"
CONFIG_FILE="${CONFIG_FILE:-/etc/knowledge-governance/backup.env}"
SUBDIRS=(target-kb-snapshots rds-logical es-snapshots logs)
PRINT_ONLY=0
[ "${1:-}" = "--print" ] && PRINT_ONLY=1
echo "备份根目录: $KB_BACKUP_ROOT"
echo "配置文件 : $CONFIG_FILE"
echo "子目录 :"
total_bytes=0
for sub in "${SUBDIRS[@]}"; do
path="$KB_BACKUP_ROOT/$sub"
if [ "$PRINT_ONLY" = "0" ]; then
mkdir -p "$path"
fi
if [ -d "$path" ]; then
usage="$(du -sh "$path" 2>/dev/null | cut -f1)"
entries="$(find "$path" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l)"
printf ' %-20s %-6s %s 个子项\n' "$sub" "$usage" "$entries"
else
printf ' %-20s (未创建)\n' "$sub"
fi
done
if [ "$PRINT_ONLY" = "1" ]; then
echo "(--print:未改动磁盘)"
exit 0
fi
mkdir -p "$(dirname "$CONFIG_FILE")"
cat >"$CONFIG_FILE" <<EOF
# 由 scripts/backup_layout.sh 生成:备份目录契约(换主机时只改这里)
KB_BACKUP_ROOT=$KB_BACKUP_ROOT
EOF
echo "已写入 $CONFIG_FILE"
echo
echo "磁盘剩余空间:"
df -h "$KB_BACKUP_ROOT" | tail -1
echo
echo "接下来说明:"
echo " 1) 各脚本通过 KB_BACKUP_ROOT 定位落点,可用 'source $CONFIG_FILE' 载入;"
echo " 2) ES 快照仓:compose 把 \$KB_BACKUP_ROOT/es-snapshots 挂到容器 /usr/share/elasticsearch/backup,"
echo " 仓库名 kb_backup(容器内路径不变,迁移目录无需重新注册仓库);"
echo " 3) 发布前门禁读取的目录 = \$KB_BACKUP_ROOT/target-kb-snapshots,容器内只读挂载;"
echo " 4) 换到生产云主机时:跑同一份脚本 → 改 /opt/*/compose.yaml 的挂载源 → 门禁配置里的 root 保持容器内路径即可。"