跳到主要内容

备份与恢复

数据保护是运维中最重要的责任。PlantPulse 通过 plantpulse-backup 模块对 PostgreSQL / Aster TSDB / 文件 / 容器卷进行统一备份。

备份命令在数据湖容器«内部»执行

plantpulse-backup 包含在 plantpulse-datalake 镜像中。因为所有数据库都在该容器中运行。

cd /opt/kopens/plantpulse-platform-docker/bin
./shell.sh # 데이터레이크 진입
cd /opt/kopens/plantpulse-platform/plantpulse-backup/bin

仅 Docker 卷备份在主机上执行(见下方 §3)。

保护对象概览​

备份工具矩阵​

工具对象方式压缩去重
pgBackRestPostgreSQL全量 / 差异 / 增量gzip / zstd✓
MedusaAster TSDB全量 / 差异 (快照)gzip-
Restic文件 / 目录增量zstd✓
rc mirrorRustFS增量同步--
backup-volume.shDocker 卷tar.gz 快照gzip-

RPO / RTO 建议目标​

数据RPO (恢复时点)RTO (恢复时间)建议备份频率
PostgreSQL 元数据1小时30分钟每日1次全量 + 每小时 WAL
Aster TSDB 时序24小时2小时每日1次差异 + 每周1次全量
RustFS 对象24小时4小时外部 S3 镜像 + 每日1次
配置 / 证书变更时15分钟变更时立即备份 + 每月1次

运行级数据中心: 以上目标基于单站点简单运行标准。如需 Multi-AZ / Geo-redundant,请同步设计外部站点复制 (rsync, rc mirror, Kafka MirrorMaker)。

备份存储结构​

/data1/pp-backup/
├── pgbackrest/postgres/ # PostgreSQL 백업 (pgBackRest)
│ ├── archive/ # WAL archive
│ └── backup/ # Full / Diff / Incr
├── medusa/ # Cassandra 백업 (Medusa)
│ └── <hostname>/<backup-name>/
├── restic/ # 파일 백업 (Restic)
│ ├── data/
│ ├── index/
│ └── snapshots/
└── docker-volume/ # Docker 볼륨 (tar.gz)
├── pp-data-YYYYMMDD.tar.gz
├── pp-security-YYYYMMDD.tar.gz
└── ...

1. plantpulse-backup 统一命令​

plantpulse-backup 模块封装了所有备份工具。

初始安装 (仅限首次)​

cd /opt/kopens/plantpulse-platform/plantpulse-backup/bin
./backup.sh --install

自动执行:

  • pgBackRest 配置 (/etc/pgbackrest/pgbackrest.conf)
  • Medusa 配置 (/etc/medusa/medusa.ini)
  • 创建目录 / 权限
  • 创建 pgBackRest stanza

PostgreSQL 备份​

cd /opt/kopens/plantpulse-platform/plantpulse-backup/bin

./backup.sh --postgres # Differential (기본, 빠름)
./backup.sh --postgres full # Full (전체)
./backup.sh --postgres incr # Incremental (가장 빠름)

Aster TSDB 备份​

./backup.sh --cassandra # Differential
./backup.sh --cassandra full # Full

文件备份 (Restic)​

/opt/kopens/plantpulse-platform/plantpulse-backup/etc/run_restic.sh
  • /data1/pp-data 增量备份
  • 保留策略:最近 7 天 + 每月 1 个
  • 自动完整性检查

备份清理​

./backup.sh --purge
  • pgBackRest: repo1-retention-full (默认 2 套)
  • Medusa: CASS_PURGE_KEEP_DAYS (默认 10 天)
  • Restic: 根据策略自动清理

2. 自动备份 — 已默认开启​

无需安装

自动备份默认开启。无需单独运行安装计划的命令。

任务职责
postgres-diffPostgreSQL 差异备份
postgres-fullPostgreSQL 全量备份
cassandra-diffAster TSDB 差异备份
cassandra-fullAster TSDB 全量备份
purge保留策略清理
并非 systemd 定时器 — 已于 2026-09-08 变更

数据湖镜像中既没有 systemd 也没有 crontab(PID 1 为入口点本身)。 计划存储在数据湖 DB 的 backup_schedule 表中,每项任务一行, 由 plantpulse-datalake-admin-api 中的 Quartz 调度器(仅在 PP_MODE=MASTER 中)读取并触发。

pd backup schedule # 읽기
pd backup schedule set --job <잡> --cron "<초 분 시 일 월 요일>"
pd backup schedule reset [--job <잡>]

请勿尝试通过 systemctl list-timers 查找 — 将无结果。

:::

默认计划​

作业OnCalendar时间
PostgreSQL Diff*-*-* 01:30:00每日 01:30
PostgreSQL FullSun *-*-* 01:00:00每周日 01:00
Aster TSDB Diff*-*-* 01:20:00每日 01:20
Aster TSDB FullSun *-*-* 00:10:00每周日 00:10
PurgeSun *-*-* 03:00:00每周日 03:00

开启与关闭​

在主机的 Secret Sidecar 中写入开关并重启。

# 호스트에서
sudo vi /etc/kopens/plantpulse-platform.env
# export PP_BACKUP_SCHEDULE_ENABLED=false

cd /opt/kopens/plantpulse-platform-docker/bin
./restart.sh
「关闭」并非失败,而是第三列状态

定时器本身始终触发,包装脚本读取开关进行判断。若处于关闭状态,将跳过备份并在 日志与 history.jsonl 中记录为 result="skipped" — 而非 ok 或 fail。因此,事后可以将«关闭»与«运行»区分开来。

请勿直接修改单元文件进行关闭。下次镜像构建重新加载原文件时,将静默恢复开启状态。

开关必须写入 Sidecar

若将 export PP_BACKUP_SCHEDULE_ENABLED=false 仅写入 bin/env.sh,将无法触达容器。 compose 将此名称传递给容器的配置行是开关的全部,其值来源于 Sidecar (或 shell export)。若写入错误,会出现«看似关闭但实际在运行»的状态。

3. Docker 卷备份 (容器环境)​

在单行安装 / Docker 安装中,可以额外进行卷级备份。

在主机上执行。

cd /opt/kopens/plantpulse-platform-docker/bin

# 기본 세트를 한 번에 (pp-data · pp-security)
./backup.sh

# 볼륨 하나만
./tools/backup-volume.sh pp-data 7 /data1/pp-backup/docker-volume
./tools/backup-volume.sh pp-security 30 /data1/pp-backup/docker-volume

默认集中缺失两个卷并非遗漏 — pp-backup 是备份的目的地(若将自身放入自身,每次体积将翻倍),而 pp-temp 对恢复无用。如需要,可通过参数指定备份。

配置模板非卷

配置模板是绑定挂载的主机目录 /etc/kopens/conf,不属于 Docker 卷备份对象。请将其作为主机文件统一备份。Secret Sidecar /etc/kopens/plantpulse-platform.env 同理。

参数说明默认
1卷名称(必填)
2保留天数7
3存储路径/data1/pp-backup/docker-volume

4. 环境变量 (backup.sh)​

变量默认说明
BACKUP_ROOT/data1/pp-backup备份根目录
PG_VER18PostgreSQL 版本
PG_DATA/data1/pp-data/postgres/dataPG 数据目录
CASS_BASE/opt/kopens/plantpulse-platform/plantpulse-storage/db/cassandraAster TSDB 安装路径
CQL_USER${PP_CASSANDRA_USER}CQL 用户
CQL_PASS${PP_CASSANDRA_PASSWORD}CQL 密码
PG_RETENTION_FULL2PG 全量保留
CASS_PURGE_KEEP_DAYS10Medusa 保留天数

5. 外部站点复制 (Off-site)​

仅凭本地备份在面对数据中心故障时较为脆弱。建议模式:

# 매일 새벽 4시 — 외부 S3 로 복제
0 4 * * * rclone sync /data1/pp-backup/ s3:kopens-pp-backup/$(hostname)/ \
--bwlimit 50M --log-file /var/log/pp-backup-sync.log

# RustFS 객체는 S3 클라이언트로 별도 미러
0 5 * * * rc mirror --overwrite local/ s3-offsite/

6. 恢复​

6.1 PostgreSQL 恢复​

# 1. plantpulse 중지 (PG 의존 모듈 + PG)
cd /opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin
./stop.sh

# 2. 백업 정보 확인
sudo -u postgres pgbackrest --stanza=pg18 info

# 3. 최신 복구
sudo -u postgres pgbackrest --stanza=pg18 restore

# 3-2. 시점 복구 (PITR)
sudo -u postgres pgbackrest --stanza=pg18 --type=time \
--target="2026-05-30 12:00:00" restore

# 4. 재시작
./start-daemon.sh
./status.sh

6.2 Aster TSDB 恢复​

# 백업 목록
medusa list-backups

# 단일 노드 복구
medusa restore-node --backup-name full_20260530_0010

# 클러스터 전체 복구 (마스터에서)
medusa restore-cluster --backup-name full_20260530_0010

注意: restore-cluster 会覆盖所有节点的数据。执行前请务必在 stage 环境中验证。

6.3 文件恢复 (Restic)​

# 스냅샷 목록
restic -r /data1/pp-backup/restic snapshots

# 최신 스냅샷 → 임시 위치 복구
restic -r /data1/pp-backup/restic restore latest --target /data1/pp-data-restored

# 특정 파일만 복구
restic -r /data1/pp-backup/restic restore latest --target / --include /data1/pp-data/cassandra/data/pp/tm_tag_point

6.4 部分时序恢复 (plantpulse-recovery)​

若仅需重新处理特定资产的特定期间数据:

cd /opt/kopens/plantpulse-platform/plantpulse-recovery/bin
./recovery.sh EQUIPMENT_000001 20260501 20260530

6.5 部分时序提取 (plantpulse-exporter)​

提取为 CSV 或通过 dsbulk 进行批量处理:

cd /opt/kopens/plantpulse-platform/plantpulse-exporter/bin

# 에셋 단위 CSV
./export.sh EQUIPMENT_000001 20260101 20260530 /tmp

# 테이블 벌크 언로드 → gz
./bulk-unload.sh pp tm_tag_point
# /data1/pp-backup/cassandra/bulk/tm_tag_point.gz

# 다시 로드
./bulk-load.sh pp tm_tag_point

7. 灾难恢复 (DR) 场景​

场景 A: 服务器硬件故障 (Cold DR)​

预计 RTO: 4~8小时 (取决于数据容量)

场景 B: 数据损坏 (PITR)​

# 1. 손상 시점 직전으로 시점 복구
./stop.sh
sudo -u postgres pgbackrest --stanza=pg18 --type=time \
--target="2026-05-30 14:30:00" restore

# 2. Cassandra 도 동일 시점 가까운 백업으로
medusa restore-cluster --backup-name diff_20260530_0120

# 3. 재시작
./start-daemon.sh
./status.sh

场景 C: 外部站点故障转移 (Hot DR)​

在外部站点维护备用集群的情况。需提前设计:

  • PostgreSQL: 流复制 (streaming replication) 或 pgBackRest 异步复制
  • Aster TSDB: multi-DC 集群 + 自动 hinted handoff
  • Kafka: MirrorMaker 2 双向复制
  • RustFS: 站点复制或 rc mirror --watch

8. 恢复后验证清单​

cd /opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin

# 1. 전체 모듈 상태
./status.sh

# 2. 헬스 체크
./ops-check.sh

# 3. Cassandra 클러스터 정상
./pd node status

# 4. PostgreSQL 연결
./pd node psql -c "SELECT count(*) FROM site;"

# 5. Kafka 토픽 / Consumer Group
./pd node topic

浏览器:

  • Web 控制台访问 (http://[HOST]/)
  • 管理员登录 (admin / admin123!)
  • 仪表板加载
  • 报警列表显示
  • OPC 连接状态为 CONNECTED
  • 时序趋势中显示最新数据
  • CEP 规则执行确认

9. 备份运维最佳实践​

  • 3-2-1 原则: 3 份数据备份, 2 种存储介质, 1 份异地存放
  • 每月 1 次恢复演练: 在 stage 环境尝试实际恢复
  • 备份完整性验证: restic check, pgbackrest verify, medusa verify
  • 备份监控: 备份失败时发送通知 (Slack, email)
  • 加密: 外部站点传输使用 TLS, 存储使用 LUKS/SSE-S3
  • 权限隔离: 备份磁盘单独挂载 + read-only 挂载选项
  • 文档化: 将恢复流程记录在运维团队共享的 wiki 中

相关文档​

技术支持​

备份 / 恢复相关咨询: webmaster@kopens.com