# バッチ設計書 9-run_backup

## 概要

本ドキュメントは、InvenTreeシステムにおけるrun_backupバッチ処理の設計仕様を定義します。このバッチは、データベースとメディアファイルの自動バックアップを実行し、データの保護と災害復旧を可能にする機能を提供します。

### 本バッチの処理概要

**業務上の目的・背景**：InvenTreeは在庫管理システムとして、部品情報、在庫データ、注文履歴、添付ファイルなど重要なビジネスデータを管理しています。システム障害、データ破損、誤操作などからデータを保護するためには、定期的なバックアップが不可欠です。本バッチは、Djangoのdbbackupおよびmediabackupコマンドを使用して、データベースとメディアファイルの圧縮バックアップを自動的に作成します。これにより、システム管理者は手動バックアップの手間を省き、確実なデータ保護を実現できます。

**バッチの実行タイミング**：日次でスケジュールされますが、バックアップ機能が有効化されている場合のみ実行されます。また、設定可能な間隔（デフォルト1日）で`check_daily_holdoff`により実行可否が判定されます。

**主要な処理内容**：
1. `INVENTREE_BACKUP_ENABLE`設定でバックアップ機能の有効/無効を確認
2. `INVENTREE_BACKUP_DAYS`設定に基づき実行可否を判定
3. `dbbackup`コマンドでデータベースバックアップを実行（圧縮、古いバックアップの削除）
4. `mediabackup`コマンドでメディアファイルバックアップを実行（圧縮、古いバックアップの削除）
5. タスク成功を記録

**前後の処理との関連**：このバッチは独立して動作しますが、`check_for_migrations`バッチの実行前にバックアップを取得することが推奨されます。復元は`invoke restore`コマンド（No.40）で実行します。

**影響範囲**：ファイルシステム（バックアップ保存先ディレクトリ）に影響します。データベースやメディアファイル自体は変更されません。

## バッチ種別

データバックアップ / システムメンテナンス

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 日次（スケジュール）/ 設定間隔（INVENTREE_BACKUP_DAYS） |
| 実行時刻 | Django-Qスケジューラ依存 |
| 実行曜日 | 毎日（ホールドオフロジックで制御） |
| 実行日 | 毎日（ホールドオフロジックで制御） |
| トリガー | Django-Qスケジューラ（DAILY） + check_daily_holdoff |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Django-Qワーカー起動 | バックグラウンドワーカープロセスが稼働していること |
| データベース接続 | データベースへの接続が確立されていること |
| バックアップ機能有効 | INVENTREE_BACKUP_ENABLE=True が設定されていること |
| ストレージ空き容量 | バックアップファイルを保存するための十分なディスク容量があること |

### 実行可否判定

- `INVENTREE_BACKUP_ENABLE`設定がFalseの場合、即座に終了（バックアップ無効）
- `check_daily_holdoff`関数により、設定間隔以内に成功していれば実行をスキップ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | 入力パラメータは不要 |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| InvenTreeGlobalSetting | DB | INVENTREE_BACKUP_ENABLE設定 |
| InvenTreeGlobalSetting | DB | INVENTREE_BACKUP_DAYS設定 |
| データベース | SQL | バックアップ対象のデータベース全体 |
| メディアファイル | ファイル | /media/ディレクトリ内のすべてのファイル |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| バックアップディレクトリ | ファイル（圧縮） | データベースバックアップファイル |
| バックアップディレクトリ | ファイル（圧縮） | メディアファイルバックアップ |
| InvenTreeGlobalSetting | DB | タスク成功日時の記録 |
| ログ | テキスト | 処理状況をstructlogで出力 |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | django-dbbackupライブラリの命名規則に従う |
| 出力先 | DBBACKUP_STORAGE_OPTIONS設定で指定されたパス |
| 文字コード | バイナリ（圧縮ファイル） |
| 圧縮形式 | gzip（compress=True） |

## 処理フロー

### 処理シーケンス

```
1. バックアップ有効化確認
   └─ INVENTREE_BACKUP_ENABLE設定を取得
   └─ Falseの場合は即座に終了
2. 実行間隔確認
   └─ INVENTREE_BACKUP_DAYS設定を取得（デフォルト1日）
   └─ check_daily_holdoffで実行可否を判定
3. データベースバックアップ
   └─ dbbackupコマンドを実行（noinput, clean, compress, interactive=False）
4. メディアファイルバックアップ
   └─ mediabackupコマンドを実行（noinput, clean, compress, interactive=False）
5. 成功記録
   └─ record_task_success('run_backup')を呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{バックアップ有効?}
    B -->|No| C[早期終了]
    B -->|Yes| D[バックアップ間隔設定を取得]
    D --> E{check_daily_holdoff通過?}
    E -->|No| F[スキップして終了]
    E -->|Yes| G[ログ出力: バックアップ開始]
    G --> H[dbbackupコマンド実行]
    H --> I[mediabackupコマンド実行]
    I --> J[タスク成功を記録]
    J --> K[バッチ終了]
    C --> L[処理終了]
    F --> L
    K --> L
```

## データベース操作仕様

### 操作別データベース影響一覧

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 設定取得 | InvenTreeGlobalSetting | SELECT | バックアップ関連設定を取得 |
| ホールドオフ確認 | InvenTreeGlobalSetting | SELECT | 前回実行日時を確認 |
| ホールドオフ記録 | InvenTreeGlobalSetting | UPDATE | 実行試行日時を記録 |
| 成功記録 | InvenTreeGlobalSetting | UPDATE | タスク成功日時を記録 |
| データベースバックアップ | 全テーブル | SELECT（読み取りのみ） | dbbackupがダンプを作成 |

### テーブル別操作詳細

#### InvenTreeGlobalSetting

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | value | key='INVENTREE_BACKUP_ENABLE' | デフォルトFalse |
| SELECT | value | key='INVENTREE_BACKUP_DAYS' | デフォルト1日 |
| UPDATE | value | key='_run_backup_ATTEMPT' | 試行日時をISO形式で保存 |
| UPDATE | value | key='_run_backup_SUCCESS' | 成功日時をISO形式で保存 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | IOError | ディスク容量不足 | バックアップ先のディスク容量を確保 |
| - | PermissionError | バックアップディレクトリへの書き込み権限なし | ディレクトリ権限を修正 |
| - | CommandError | dbbackup/mediabackupコマンドの失敗 | エラーログを確認し、設定を修正 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（明示的リトライなし） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

備考：check_daily_holdoffにより、失敗時は12時間以内の再試行を抑制

### 障害時対応

- ディスク容量不足：古いバックアップの削除または容量追加後、手動でバックアップを実行
- 権限エラー：ディレクトリ権限を修正後、次回スケジュール実行で自動復旧
- コマンドエラー：エラーログを確認し、dbbackup/mediabackup設定を確認

## トランザクション仕様

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | dbbackupコマンドが適切なトランザクション分離を管理 |
| コミットタイミング | N/A（読み取り専用） |
| ロールバック条件 | N/A |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | データベースサイズ + メディアファイルサイズ依存 |
| 目標処理時間 | データサイズに依存（数分〜数十分） |
| メモリ使用量上限 | データベースサイズに依存 |

## 排他制御

- 同時実行：Django-Qスケジューラにより1日1回のみ実行
- ロック仕様：check_daily_holdoffにより12時間以内の重複実行を防止
- データベースロック：dbbackupが適切なロックレベルを使用

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 情報ログ | バックアップ開始時 | 'Performing automated database backup task' |
| トレースログ | 処理開始時 | OpenTelemetryスパン 'run_backup' |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| バックアップ失敗 | 1回以上 | システム管理者 |
| バックアップサイズ | 異常増加（要定義） | システム管理者 |
| 処理時間 | 通常の2倍以上 | システム管理者 |
| ディスク使用率 | 80%以上 | システム管理者 |

## 備考

- 設定`INVENTREE_BACKUP_ENABLE`をTrueにしないとバックアップは実行されない（デフォルト無効）
- 設定`INVENTREE_BACKUP_DAYS`でバックアップ間隔を調整可能（デフォルト1日）
- `clean=True`オプションにより、古いバックアップが自動的に削除される（世代管理）
- `compress=True`オプションにより、バックアップファイルがgzip圧縮される
- `noinput=True`および`interactive=False`により、対話的な確認なしで実行される
- バックアップの復元には`invoke restore`コマンドを使用
- `@tracer.start_as_current_span('run_backup')`デコレータにより、OpenTelemetryによる分散トレーシングに対応
- 実装ファイル: `src/backend/InvenTree/InvenTree/tasks.py`
