文档首页 / 备份与恢复

备份与恢复

元数据库、数据目录与连接密钥必须成对备份:备份内容与工具、各部署形态的备份方法、校验演练、恢复步骤与常见故障。

概述

适用版本:v2.0.5 及之后(tools/backup.sh / tools/restore.sh 随发布包提供)。适用部署:单机 Docker Compose、原生包(systemd)、多实例集群;元数据库为 PostgreSQL 族 / MySQL 族 / 内置 H2。

铁律:元数据库、FDL_DATA_DIR 数据目录、连接密钥(FDL_CONNECTION_SECRET_KEY,或安装向导生成的 datalink.properties / connection-secret.key)必须一起备份、一起恢复。只恢复库而丢了密钥,所有已保存的数据源密码都解不开;只恢复旧密钥而库是新的,配置会回退。元数据库迁移不可逆,回滚必须连库一起恢复。

目标与保留策略

项目 建议值 说明
RPO(可接受丢多少数据) 生产不超过 15 分钟;一般不超过 2 小时 元数据库存的是配置、发布版本、运行记录、审计;数据源里的业务数据不在本备份范围
RTO(恢复要多久) 30 到 60 分钟(元数据库不超过 10 GB) 时间主要花在拉备份、数据库恢复、解包数据目录、重启与冒烟
保留策略 每日 30 份 + 每周 12 份 + 每月 12 份 至少 1 份离线或异机,备份目录本身要加密
演练频率 每季度一次,以及每次大版本升级前 用 --verify 与一次真实恢复到临时库验证

备份内容

tools/backup.sh 产出:

文件 内容
metadata-db/postgresql.dump PG 族 pg_dump -Fc(含 openGauss / 金仓,可用 PG_DUMP 指向厂商兼容工具)
metadata-db/mysql.sql MySQL / MariaDB mysqldump(--single-transaction,含 routines、triggers、events)
metadata-db/<库名>.mv.db 内置 H2 的库文件副本(必须先停服务)
data.tar.gz 整个 FDL_DATA_DIR:连接密钥、自备 JDBC 驱动、受管文件、H2 数据目录、文件传输目录
manifest.json / manifest.sha256 每个文件的 sha256 与大小、UTC 时间、产品版本、库类型、脱敏后的连接地址
RESTORE.txt 本次备份的恢复命令与密钥提醒

口令只经环境变量 PGPASSWORD 或权限 0600 的临时配置文件传给客户端,不出现在命令行、不打印;备份目录权限为 700。

日常备份

Docker Compose

宿主机通常看不到容器内的数据目录。推荐从宿主机直连元数据库,数据目录用 docker cp 取出:

export DB_URL='jdbc:postgresql://127.0.0.1:5432/dfdatalink' DB_USERNAME=fdl DB_PASSWORD='***'
mkdir -p /backup/datalink-data
docker compose cp app:/var/lib/sight-datalink/. /backup/datalink-data/   # 含密钥,请加密归档
tools/backup.sh --dir /backup/datalink --data-dir /backup/datalink-data

也可以在 app 容器内运行脚本,但容器内默认没有 pg_dump / mysqldump,需要自行安装客户端,生产环境更推荐上面的方式。

原生包(systemd,元数据库外部)

sudo install -d -m 700 /backup/datalink
DB_PASSWORD="$(sudo sed -n 's/^DB_PASSWORD=//p' /opt/sight-datalink/sight-datalink.env)" \
  sudo -E tools/backup.sh --dir /backup/datalink --data-dir /opt/sight-datalink/data

内置 H2(必须停服务)

sudo systemctl stop sight-datalink
tools/backup.sh --dir /backup/datalink --data-dir /opt/sight-datalink/data \
  --db-url 'jdbc:h2:file:/opt/sight-datalink/data/db/dfdatalink'
sudo systemctl start sight-datalink

脚本会通过 lsof / fuser 与 .lock.db 检测占用,服务运行时拒绝复制。容器内探测不到时,必须先停容器,再加 --assume-stopped,并在事后校验。停机窗口就是 H2 的备份窗口,这也是生产不建议用 H2 的原因之一。

非 Linux 环境

tools/backup.sh / tools/restore.sh 是 bash 脚本,在 Linux 之外同样可用,但要注意:

  • Docker Desktop(macOS / Windows):数据目录在虚拟机里,用 docker compose cp 取出后再备份;内置 H2 必须先 docker compose stop app,再按提示使用 --assume-stopped。
  • macOS 本地:显式用 bash tools/backup.sh … 调用;没有 sha256sum 时脚本自动回退到 shasum -a 256。
  • Windows:优先在 WSL2 中运行,把备份放在 WSL 文件系统而不是 /mnt/c。
  • Time Machine、文件历史、云盘同步不能替代数据库一致性备份,只能作为额外副本。

定时备份

# 每天 02:30(示例,先手动跑通再启用)
30 2 * * *  cd /opt/sight-datalink && DB_URL=... DB_USERNAME=... DB_PASSWORD=... \
            tools/backup.sh --dir /backup/datalink >> /var/log/fdl-backup.log 2>&1

备份失败要接入通知(cron 默认只发本地邮件);建议再加一条外部告警:备份目录最后修改时间超过 26 小时。

校验与演练

# 校验清单、sha256、归档完整性与目标库连通性(只读,不写任何数据)
tools/restore.sh --dir /backup/datalink/sight-datalink-backup-20261030T020000Z \
  --db-url 'jdbc:postgresql://db:5432/datalink' --db-user fdl \
  --data-dir /tmp/fdl-restore-drill --verify

--verify 会校验 manifest.sha256、逐个文件的 sha256 与大小、data.tar.gz 是否可解包,以及目标库族一致性与连通性。

季度演练:把备份恢复到临时库与临时目录,启动一个临时实例(换端口),登录、打开一个数据源「测试连接」、抽查运行记录,记录实际 RTO,完成后删除临时实例。

恢复步骤

# 0. 先停服务(H2 必须;外部库也建议停,避免恢复期间写入)
sudo systemctl stop sight-datalink        # 或 docker compose stop app

# 1. 恢复(会覆写目标元数据库;旧数据目录改名为 <data-dir>.pre-restore-<UTC> 保留)
tools/restore.sh --dir '/backup/datalink/sight-datalink-backup-20261030T020000Z' \
  --db-url 'jdbc:postgresql://db:5432/datalink' --db-user fdl --db-password '***' \
  --data-dir /opt/sight-datalink/data --yes

# 2. 确认连接密钥:环境变量部署要设回与备份时相同的 FDL_CONNECTION_SECRET_KEY;
#    向导部署确认 data/datalink.properties / connection-secret.key 已随数据目录恢复。

# 3. 启动并冒烟
sudo systemctl start sight-datalink
  • 跨版本恢复:恢复后的库对应备份时的产品版本。若当前程序更新,先换回同版本,再按正常流程升级;不支持把元数据库原地降级。
  • 恢复到新机器:先安装同版本,准备空数据目录与空库,再执行 restore.sh;不要先让新实例跑迁移建表,PostgreSQL 恢复使用 --clean --if-exists,会先删除目标库里的对象。

保管与访问控制

  • 备份目录包含连接密钥与全部配置,按生产数据对待:归档后再加密(age / gpg / 云 KMS),加密口令与备份分开存放。
  • 至少 2 份,其中 1 份离线或对象存储(不可变 / 版本化);上传后核对 manifest.sha256。
  • 备份账号只需要只读库权限加数据目录读权限;不要把生产 DB_PASSWORD 写进 crontab。
  • 团队至少两人掌握恢复流程;恢复权限与生产库写权限同等敏感。

恢复后冒烟清单

  1. GET /api/health 与 GET /api/health/ready 均返回 200。
  2. 管理员登录成功;用户、角色、最近编辑的任务与管道在列表里。
  3. 打开一个数据源点「测试连接」:能解密密码且能连目标库(证明密钥与库匹配)。
  4. 运行记录里能看到历史记录;手动跑一个小任务成功。
  5. 平台日志里能看到本次登录的审计记录;GET /api/system/actuator/prometheus 可抓取。
  6. 旧数据目录 <data-dir>.pre-restore-<UTC> 保留,观察 1 到 2 天后再清理。
  7. 记录恢复开始与结束时间、实际 RTO;超过目标则更新目标并补演练。

常见故障

现象 处理
pg_restore 报 version mismatch 使用不低于备份服务器主版本的 pg_restore
pg_restore 中途失败 目标库可能半恢复:清空目标库重建后再跑一次 restore.sh,不要直接启动服务
起服务后数据源「凭据不可读取」 密钥与库不匹配:设回备份时的 FDL_CONNECTION_SECRET_KEY,或恢复随包的 connection-secret.key / datalink.properties
H2 提示文件被占用 服务没停干净:停止后确认 lsof <库>.mv.db 为空再重试
MySQL 恢复报 utf8mb4 字符集错误 目标库需使用 CHARACTER SET utf8mb4 COLLATE utf8mb4_bin
备份目录被删但服务仍正常 仍在运行的连接密钥无法恢复,只能重新录入数据源密码;先补一份新备份并检查保留策略

与升级的衔接

  • 升级前必须完成一次校验通过的备份,并在升级记录里写明备份路径与 manifest.sha256,见 升级与回滚。升级前体检脚本 tools/preupgrade-check.sh --backup-dir <备份目录> 会把最近备份的年龄与 manifest 校验纳入检查。
  • 回滚 = 恢复库 + 数据目录 + 密钥,三者缺一不可;不允许原地降级,也不允许只换回旧 jar 而不恢复库。
  • 多实例集群没有自动跨实例一致性快照,备份期间其他实例仍可能写入。生产建议在固定维护窗口内先停全部实例再备份,或接受 RPO 内的少量丢失并在恢复后核对运行记录。

演练记录模板

日期:            演练人:
备份目录 / sha256:
备份时版本:      恢复目标版本:
开始时间:        恢复完成时间:      实际 RTO:
校验(--verify):通过 / 失败(原因)
冒烟 1–6 项:      1☐ 2☐ 3☐ 4☐ 5☐ 6☐
发现的问题:      下次改进:

相关文档

联系我们

请填写您的信息,我们将在 1 个工作日内与您联系。