バックアップと復旧
データ保護は 運用の最重要責務 です。PlantPulse は plantpulse-backup モジュールを通じて PostgreSQL / Cassandra / ファイル / コンテナボリュームを統合バックアップします。
plantpulse-backup は plantpulse-datalake イメージ内に含まれています。データベースがすべてそのコンテナで実行されるためです。
cd /opt/kopens/plantpulse-platform-docker/bin
./shell.sh # 데이터레이크 진입
cd /opt/kopens/plantpulse-platform/plantpulse-backup/bin
Dockerボリュームバックアップのみホストから 実行します(以下 §3)。
保護対象の概観
バックアップツールマトリックス
| ツール | 対象 | 方式 | 圧縮 | 重複排除 |
|---|---|---|---|---|
| pgBackRest | PostgreSQL | Full / Differential / Incremental | gzip / zstd | ✓ |
| Medusa | Cassandra | Full / Differential(スナップショット) | gzip | - |
| Restic | ファイル / ディレクトリ | 増分 | zstd | ✓ |
| mc mirror | MinIO | 増分同期 | - | - |
| backup-volume.sh | Dockerボリューム | tar.gz スナップショット | gzip | - |
RPO / RTO 推奨目標
| データ | RPO(復旧時点) | RTO(復旧時間) | 推奨バックアップ頻度 |
|---|---|---|---|
| PostgreSQL メタ | 1時間 | 30分 | 日1回 Full + 時間別 WAL |
| Cassandra 時系列 | 24時間 | 2時間 | 日1回 Diff + 週1回 Full |
| MinIO オブジェクト | 24時間 | 4時間 | 外部 S3 ミラー + 日1回 |
| 設定 / 証明書 | 変更時 | 15分 | 変更時即時 + 月1回 |
エンタープライズ級データセンター: 上記目標は単一サイト単純運用を基準としています。Multi-AZ / Geo-redundant が必要な場合は、外部サイト複製(rsync、mc 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 (가장 빠름)
Cassandra バックアップ
./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. 自動バックアップ — すでに有効です
自動バックアップは イメージにsystemd タイマー5個として組み込まれ、デフォルトで有効 です。--cron-install を実行する必要はありません。
| タイマー | 機能 |
|---|---|
plantpulse-backup-postgres-diff | PostgreSQL Differential |
plantpulse-backup-postgres-full | PostgreSQL Full |
plantpulse-backup-cassandra-diff | Cassandra Differential |
plantpulse-backup-cassandra-full | Cassandra Full |
plantpulse-backup-purge | 保存ポリシークリーンアップ |
デフォルトスケジュール
| 作業 | OnCalendar | 時刻 |
|---|---|---|
| PostgreSQL Diff | *-*-* 01:30:00 | 毎日 01:30 |
| PostgreSQL Full | Sun *-*-* 01:00:00 | 毎週日曜 01:00 |
| Cassandra Diff | *-*-* 01:20:00 | 毎日 01:20 |
| Cassandra Full | Sun *-*-* 00:10:00 | 毎週日曜 00:10 |
| Purge | Sun *-*-* 03:00:00 | 毎週日曜 03:00 |
有効/無効の切り替え
ホストの Secret サイドカーにスイッチを記入して再起動します。
# 호스트에서
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 でもありません。したがって後で「無効」と「実行」を区別できます。
ユニットファイルを直接編集して無効にしないでください。次のイメージビルドが元のファイルを復元すると、サイレントに再度有効になります。
export PP_BACKUP_SCHEDULE_ENABLED=false を bin/env.sh にのみ記入すると コンテナに到達しません。 compose がこの名前をコンテナに渡す行がスイッチのすべてであり、その値はサイドカー(または 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
デフォルトセットで2つが除外されているのは忘れてではありません — pp-backup はバックアップの 保存先 だからです(自身を自身の内部にバックアップすると毎回2倍になります)、pp-temp は復旧に不要だからです。必要な場合は引数で指定してバックアップできます。
設定テンプレートはホストディレクトリ /etc/kopens/conf をバインドマウントしたものなので、Dockerボリュームバックアップ対象ではありません。ホストファイルとして合わせてバックアップしてください。Secret サイドカー /etc/kopens/plantpulse-platform.env も同様です。
| 引数 | 説明 | デフォルト |
|---|---|---|
| 1 | ボリューム名 | (必須) |
| 2 | 保存日数 | 7 |
| 3 | 保存パス | /data1/pp-backup/docker-volume |
4. 環境変数(backup.sh)
| 変数 | デフォルト | 説明 |
|---|---|---|
BACKUP_ROOT | /data1/pp-backup | バックアップルート |
PG_VER | 18 | PostgreSQL バージョン |
PG_DATA | /data1/pp-data/postgres/data | PG データディレクトリ |
CASS_BASE | /opt/kopens/plantpulse-platform/plantpulse-storage/db/cassandra | Cassandra インストールパス |
CQL_USER | ${PP_CASSANDRA_USER} | CQL ユーザー |
CQL_PASS | ${PP_CASSANDRA_PASSWORD} | CQL パスワード |
PG_RETENTION_FULL | 2 | PG Full 保存期間 |
CASS_PURGE_KEEP_DAYS | 10 | Medusa 保存日数 |
5. オフサイト複製
ローカルバックアップのみでは、データセンター障害に脆弱です。推奨パターン:
# 매일 새벽 4시 — 외부 S3 로 복제
0 4 * * * rclone sync /data1/pp-backup/ s3:kopens-pp-backup/$(hostname)/ \
--bwlimit 50M --log-file /var/log/pp-backup-sync.log
# MinIO 객체는 mc 로 별도 미러
0 5 * * * mc 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 Cassandra 復旧
# 백업 목록
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 ASSET_01032 20260501 20260530
6.5 部分時系列抽出(plantpulse-exporter)
CSV で抽出または dsbulk でバルク処理:
cd /opt/kopens/plantpulse-platform/plantpulse-exporter/bin
# 에셋 단위 CSV
./export.sh ASSET_01032 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)
オフサイトに standby クラスタを維持する場合。事前設計が必要:
- PostgreSQL: ストリーミングレプリケーション または pgBackRest 非同期複製
- Cassandra: multi-DC クラスタ + 自動 hinted handoff
- Kafka: MirrorMaker 2 双方向複製
- MinIO: site replication または
mc 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
ブラウザ:
- ウェブコンソールアクセス(
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