Backup und Wiederherstellung
Datenschutz ist die wichtigste Verantwortung im Betrieb. PlantPulse sichert PostgreSQL / Aster TSDB / Dateien / Container-Volumes integriert über das plantpulse-backup Modul.
plantpulse-backup befindet sich im plantpulse-datalake Image, da alle Datenbanken in diesem Container laufen.
cd /opt/kopens/plantpulse-platform-docker/bin
./shell.sh # 데이터레이크 진입
cd /opt/kopens/plantpulse-platform/plantpulse-backup/bin
Nur Docker-Volume-Backups werden auf dem Host durchgeführt (siehe §3 unten).
Überblick über Schutzobjekte
Matrix der Backup-Tools
| Tool | Ziel | Methode | Kompression | Deduplizierung |
|---|---|---|---|---|
| pgBackRest | PostgreSQL | Full / Differential / Incremental | gzip / zstd | ✓ |
| Medusa | Aster TSDB | Full / Differential (Snapshot) | gzip | - |
| Restic | Dateien / Verzeichnisse | Inkrementell | zstd | ✓ |
| rc mirror | RustFS | Inkrementelle Synchronisation | - | - |
| backup-volume.sh | Docker Volume | tar.gz Snapshot | gzip | - |
Empfohlene RPO / RTO Ziele
| Daten | RPO (Wiederherstellungspunkt) | RTO (Wiederherstellungszeit) | Empfohlene Backup-Frequenz |
|---|---|---|---|
| PostgreSQL Meta | 1 Stunde | 30 Minuten | 1x täglich Full + stündlich WAL |
| Aster TSDB Zeitreihe | 24 Stunden | 2 Stunden | 1x täglich Diff + 1x wöchentlich Full |
| RustFS Objekte | 24 Stunden | 4 Stunden | Externer S3 Mirror + 1x täglich |
| Konfiguration / Zertifikate | Bei Änderung | 15 Minuten | Sofort bei Änderung + 1x monatlich |
Rechenzentren für Betriebsklassen: Die obigen Ziele gelten für den einfachen Betrieb eines Standorts. Wenn Multi-AZ / Geo-Redundanz erforderlich ist, planen Sie bitte eine externe Standortreplikation (rsync, rc mirror, Kafka MirrorMaker) mit ein.
Struktur der Backup-Speicherung
/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. Integrierte plantpulse-backup Befehle
Das plantpulse-backup Modul kapselt alle Backup-Tools.
Erstinstallation (einmalig)
cd /opt/kopens/plantpulse-platform/plantpulse-backup/bin
./backup.sh --install
Automatische Ausführung:
- pgBackRest Konfiguration (
/etc/pgbackrest/pgbackrest.conf) - Medusa Konfiguration (
/etc/medusa/medusa.ini) - Erstellung von Verzeichnissen / Berechtigungen
- Erstellung der pgBackRest Stanza
PostgreSQL Backup
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
./backup.sh --cassandra # Differential
./backup.sh --cassandra full # Full
Dateisicherung (Restic)
/opt/kopens/plantpulse-platform/plantpulse-backup/etc/run_restic.sh
/data1/pp-datainkrementelles Backup- Aufbewahrungsrichtlinie: Letzte 7 Tage + 1 pro Monat
- Automatische Integritätsprüfung
Backup-Bereinigung
./backup.sh --purge
- pgBackRest:
repo1-retention-full(Standard 2 Sätze) - Medusa:
CASS_PURGE_KEEP_DAYS(Standard 10 Tage) - Restic: Automatisch gemäß Richtlinie
2. Automatische Backups — bereits aktiviert
Automatische Backups sind standardmäßig aktiviert. Es ist nicht notwendig, separate Befehle zur Einrichtung des Zeitplans auszuführen.
| Job | Funktion |
|---|---|
postgres-diff | PostgreSQL Differential |
postgres-full | PostgreSQL Full |
cassandra-diff | Aster TSDB Differential |
cassandra-full | Aster TSDB Full |
purge | Bereinigung der Aufbewahrungsrichtlinie |
Das Data Lake Image enthält weder systemd noch crontab (PID 1 ist der Entrypoint selbst).
Die Zeitpläne sind in der Tabelle backup_schedule der Data Lake DB als eine Zeile pro Job hinterlegt.
Der Quartz Scheduler innerhalb von plantpulse-datalake-admin-api liest diese (nur in PP_MODE=MASTER) aus und löst sie aus.
pd backup schedule # 읽기
pd backup schedule set --job <잡> --cron "<초 분 시 일 월 요일>"
pd backup schedule reset [--job <잡>]
Suchen Sie nicht mit systemctl list-timers — es wird nichts gefunden.
:::
Standard-Zeitplan
| Aufgabe | OnCalendar | Zeit |
|---|---|---|
| PostgreSQL Diff | *-*-* 01:30:00 | Täglich 01:30 |
| PostgreSQL Full | Sun *-*-* 01:00:00 | Jeden Sonntag 01:00 |
| Aster TSDB Diff | *-*-* 01:20:00 | Täglich 01:20 |
| Aster TSDB Full | Sun *-*-* 00:10:00 | Jeden Sonntag 00:10 |
| Purge | Sun *-*-* 03:00:00 | Jeden Sonntag 03:00 |
Aktivieren und Deaktivieren
Schreiben Sie den Schalter in den Secret-Sidecar des Hosts und starten Sie neu.
# 호스트에서
sudo vi /etc/kopens/plantpulse-platform.env
# export PP_BACKUP_SCHEDULE_ENABLED=false
cd /opt/kopens/plantpulse-platform-docker/bin
./restart.sh
Der Timer selbst feuert immer, aber das Wrapper-Skript liest den Schalter und entscheidet. Wenn er ausgeschaltet ist, wird das Backup übersprungen und dies wird als Incident im Journal und in history.jsonl als result="skipped" aufgezeichnet — nicht als ok oder fail. So lassen sich «ausgeschaltet» und «ausgeführt» später unterscheiden.
Deaktivieren Sie die Funktion nicht durch direktes Ändern der Unit-Dateien. Beim nächsten Image-Build werden die Originale wiederhergestellt und die Funktion wird stillschweigend reaktiviert.
Wenn Sie export PP_BACKUP_SCHEDULE_ENABLED=false nur in bin/env.sh eintragen, wird dies nicht an den Container übertragen. Die Zeile in der compose-Datei, die diesen Namen an den Container weitergibt, ist das Einzige, was vom Schalter übrig bleibt; der Wert selbst kommt aus dem Sidecar (oder einem Shell-Export). Bei falscher Eintragung entsteht ein Zustand, der «ausgeschaltet aussieht, aber trotzdem weiterläuft».
3. Docker Volume Backup (Container-Umgebung)
Bei One-Line-Installationen oder Docker-Installationen ist ein zusätzliches Backup auf Volume-Ebene möglich.
Ausführen auf dem Host.
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
Dass zwei Volumes im Standardsatz fehlen, ist kein Versehen — pp-backup ist das Ziel des Backups (was die Größe bei jeder Durchführung verdoppeln würde) und pp-temp ist für die Wiederherstellung nicht nützlich. Falls benötigt, können diese als Argument angegeben werden.
Konfigurationsvorlagen sind Bind-Mounts des Host-Verzeichnisses /etc/kopens/conf und somit keine Docker-Volume-Backup-Ziele. Sichern Sie diese bitte als Host-Dateien. Dies gilt ebenso für den Secret-Sidecar /etc/kopens/plantpulse-platform.env.
| Argument | Beschreibung | Standard |
|---|---|---|
| 1 | Volume-Name | (Erforderlich) |
| 2 | Aufbewahrungsdauer (Tage) | 7 |
| 3 | Speicherpfad | /data1/pp-backup/docker-volume |
4. Umgebungsvariablen (backup.sh)
| Variable | Standard | Beschreibung |
|---|---|---|
BACKUP_ROOT | /data1/pp-backup | Backup-Root |
PG_VER | 18 | PostgreSQL Version |
PG_DATA | /data1/pp-data/postgres/data | PG Datenverzeichnis |
CASS_BASE | /opt/kopens/plantpulse-platform/plantpulse-storage/db/cassandra | Aster TSDB Installationspfad |
CQL_USER | ${PP_CASSANDRA_USER} | CQL Benutzer |
CQL_PASS | ${PP_CASSANDRA_PASSWORD} | CQL Passwort |
PG_RETENTION_FULL | 2 | PG Full Aufbewahrung |
CASS_PURGE_KEEP_DAYS | 10 | Medusa Aufbewahrungsdauer |
5. Externe Standortreplikation (Off-site)
Lokale Backups allein sind anfällig für Rechenzentrumsausfälle. Empfohlenes Muster:
# 매일 새벽 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. Wiederherstellung
6.1 PostgreSQL Wiederherstellung
# 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 Wiederherstellung
# 백업 목록
medusa list-backups
# 단일 노드 복구
medusa restore-node --backup-name full_20260530_0010
# 클러스터 전체 복구 (마스터에서)
medusa restore-cluster --backup-name full_20260530_0010
Achtung:
restore-clusterüberschreibt die Daten aller Knoten. Bitte validieren Sie dies unbedingt in einer Stage-Umgebung vor der Ausführung.
6.3 Dateiwiederherstellung (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 Partielle Zeitreihen-Wiederherstellung (plantpulse-recovery)
Um nur Daten eines bestimmten Zeitraums für ein bestimmtes Asset neu zu verarbeiten:
cd /opt/kopens/plantpulse-platform/plantpulse-recovery/bin
./recovery.sh EQUIPMENT_000001 20260501 20260530
6.5 Partielle Zeitreihen-Extraktion (plantpulse-exporter)
Extraktion als CSV oder Bulk-Verarbeitung mit 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. Disaster Recovery (DR) Szenarien
Szenario A: Server-Hardwareausfall (Cold DR)
Erwartetes RTO: 4~8 Stunden (abhängig von der Datenmenge)
Szenario B: Datenkorruption (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
Szenario C: Externer Standort-Failover (Hot DR)
Falls ein Standby-Cluster an einem externen Standort unterhalten wird. Vorherige Planung erforderlich:
- PostgreSQL: Streaming Replication oder pgBackRest asynchrone Replikation
- Aster TSDB: Multi-DC Cluster + automatischer Hinted Handoff
- Kafka: MirrorMaker 2 bidirektionale Replikation
- RustFS: Site Replication oder
rc mirror --watch
8. Checkliste zur Validierung nach Wiederherstellung
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
Browser:
- Zugriff auf Web-Konsole (
http://[HOST]/) - Administrator-Login (
admin / admin123!) - Laden des Dashboards
- Anzeige der Alarm-Liste
- OPC Verbindungsstatus CONNECTED
- Anzeige aktueller Daten in Zeitreihen-Trends
- Ausführung von CEP-Regeln bestätigt
9. Best Practices für den Backup-Betrieb
- 3-2-1 Regel: 3 Kopien der Daten, 2 Medien, 1 Offsite
- Monatliche Wiederherstellungsübung: Tatsächlicher Wiederherstellungsversuch in der Stage-Umgebung
- Backup-Integritätsprüfung:
restic check,pgbackrest verify,medusa verify - Backup-Überwachung: Benachrichtigung bei Backup-Fehlern (Slack, E-Mail)
- Verschlüsselung: TLS bei Übertragung an externe Standorte, LUKS/SSE-S3 bei Speicherung
- Berechnungstrennung: Backup-Disk separat mounten + Read-Only Mount-Option
- Dokumentation: Wiederherstellungsverfahren im gemeinsam genutzten Wiki des Betriebsteams festhalten
Verwandte Dokumente
Technischer Support
Anfragen zu Backup / Wiederherstellung: webmaster@kopens.com