# 機能設計書 64-スナップショットリストア

## 概要

本ドキュメントは、OpenSearchのスナップショットリストア機能に関する機能設計書である。本機能はスナップショットからインデックスを復元するRestoreServiceを中心に実装されており、リストア処理を複数段階（メタデータ読み取り、インデックス作成、シャードリカバリ）に分けて実行する。

### 本機能の処理概要

**業務上の目的・背景**：データ障害やオペレーションミスからの復旧、テスト環境へのデータ復元、クラスタ間のデータ移行などにおいて、スナップショットからインデックスを復元する機能が不可欠である。

**機能の利用シーン**：障害復旧時のデータリストア、異なるクラスタへのデータ移行、特定時点へのデータロールバック、テスト環境構築等に利用される。

**主要な処理内容**：
1. スナップショットメタデータの読み取り
2. リストア前提条件の検証（インデックス存在確認、設定互換性等）
3. グローバル状態のリストア（オプション）
4. インデックスメタデータの復元とインデックス作成
5. RoutingTable更新によるシャードリカバリの開始
6. シャード単位のデータリカバリ（SnapshotRecoverySource）
7. リストア完了後のRestoreInProgressクリーンアップ

**関連システム・外部連携**：RepositoriesServiceを通じてスナップショットリポジトリにアクセスする。AllocationServiceによりシャードのノード配置が決定される。

**権限による制御**：スナップショットリストアにはクラスタ管理者権限が必要。リストア先インデックスが既に存在する場合はクローズされている必要がある。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 124 | スナップショットリストア | 主機能 | スナップショットからインデックスを復元する処理 |

## 機能種別

データ復元 / CRUD操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| repository | String | Yes | リポジトリ名 | 登録済みリポジトリ名 |
| snapshot | String | Yes | スナップショット名 | 存在するスナップショット名 |
| indices | String[] | No | リストア対象インデックス名 | スナップショットに含まれるインデックス |
| ignore_unavailable | boolean | No | 利用不可インデックスを無視 | デフォルトfalse |
| include_global_state | boolean | No | グローバル状態をリストアするか | デフォルトfalse |
| include_aliases | boolean | No | エイリアスをリストアするか | デフォルトtrue |
| rename_pattern | String | No | リネーム用の正規表現パターン | 有効な正規表現 |
| rename_replacement | String | No | リネーム用の置換文字列 | 有効な文字列 |
| index_settings | Settings | No | リストア時に上書きするインデックス設定 | 有効なインデックス設定 |
| ignore_index_settings | String[] | No | リストア時に無視するインデックス設定 | 有効な設定名 |
| source_remote_store_repository | String | No | リモートストアリポジトリ名 | リモートストアバックドインデックスの場合 |
| storage_type | String | No | ストレージタイプ（local/remote_snapshot） | 有効なタイプ名 |

### 入力データソース

REST API（POST /_snapshot/{repository}/{snapshot}/_restore）、スナップショットリポジトリ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| snapshot | String | リストア元スナップショット名 |
| indices | String[] | リストアされたインデックス一覧 |
| shards.total | int | 総シャード数 |
| shards.successful | int | 成功シャード数 |
| shards.failed | int | 失敗シャード数 |

### 出力先

REST APIレスポンス、クラスタ状態（RestoreInProgress）

## 処理フロー

### 処理シーケンス

```
1. RestoreSnapshotRequestを受信
   └─ バリデーション（リポジトリ存在確認、スナップショット存在確認）
2. リポジトリからスナップショットメタデータを読み取り
   └─ SnapshotInfo、インデックスメタデータの取得
3. リストア前提条件の検証
   └─ 既存インデックスとの競合チェック、設定互換性検証
4. グローバル状態のリストア（オプション）
   └─ テンプレート、永続的設定等のリストア
5. インデックスメタデータの復元・設定上書き
   └─ rename_pattern/rename_replacementによるインデックス名変更
   └─ index_settingsによる設定上書き
6. クラスタ状態更新
   └─ RestoreInProgressエントリ追加、RoutingTable更新
7. シャード単位のリカバリ開始
   └─ SnapshotRecoverySourceとしてリカバリ実行
8. 全シャードリカバリ完了後にRestoreInProgressをクリーンアップ
```

### フローチャート

```mermaid
flowchart TD
    A[RestoreSnapshotRequest] --> B[スナップショットメタデータ読取]
    B --> C[前提条件検証]
    C --> D{グローバル状態リストア?}
    D -->|Yes| E[テンプレート・設定リストア]
    D -->|No| F[インデックスメタデータ復元]
    E --> F
    F --> G[インデックス名リネーム]
    G --> H[インデックス設定上書き]
    H --> I[ClusterState更新]
    I --> J[RoutingTable更新]
    J --> K[シャードリカバリ開始]
    K --> L{全シャード完了?}
    L -->|No| M[リカバリ継続]
    M --> L
    L -->|Yes| N[RestoreInProgressクリーンアップ]
    N --> O[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-64-01 | インデックス競合チェック | リストア先インデックスが既に存在しオープン状態の場合はエラー | リストア実行時 |
| BR-64-02 | リモートストア設定不変 | リモートストア関連設定（SETTING_REMOTE_STORE_ENABLED等）はユーザーが変更不可 | リストア時の設定上書き |
| BR-64-03 | レプリカ数不変 | SETTING_NUMBER_OF_REPLICASは削除不可（USER_UNREMOVABLE_SETTINGS） | リストア時の設定変更 |
| BR-64-04 | シャード数制限 | ShardLimitValidatorによるシャード数上限チェック | リストア実行時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| メタデータ読取 | リポジトリBlobStore | READ | スナップショットメタデータ・インデックスメタデータの読取 |
| インデックス作成 | クラスタ状態 | INSERT | 新規インデックスメタデータの作成 |
| シャードリカバリ | リポジトリBlobStore/ローカルディスク | READ/WRITE | スナップショットデータの読取・ローカルへの書込 |
| 状態管理 | クラスタ状態 | UPDATE | RestoreInProgressの更新 |

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

#### クラスタ状態

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | IndexMetadata | スナップショットからリストアされたメタデータ | リネーム・設定上書き適用後 |
| UPDATE | RoutingTable | SnapshotRecoverySourceによるリカバリルート | addAsRestoreで追加 |
| UPDATE | RestoreInProgress | リストア進行状況 | 全シャード完了後に削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| SnapshotRestoreException | リストアエラー | リストア前提条件の違反 | エラーメッセージに従って対処 |
| RepositoryMissingException | リポジトリエラー | リポジトリが存在しない | リポジトリを登録 |
| SnapshotMissingException | スナップショットエラー | スナップショットが存在しない | スナップショット名を確認 |
| IllegalArgumentException | パラメータエラー | 不正なリネームパターンやインデックス設定 | パラメータを修正 |

### リトライ仕様

シャードリカバリは通常のリカバリ機構を使用し、失敗時はシャードアロケーションの再割り当てでリトライされる。

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

リストア操作はClusterStateUpdateTaskを通じて実行され、クラスタ状態の一貫性はクラスタマネージャにより保証される。シャードリカバリは個々に独立して実行される。

## パフォーマンス要件

- storage_type=remote_snapshotにより、リモートストレージから直接検索可能（Searchable Snapshot相当）
- 並列シャードリカバリによる高速リストア
- データキャッシュサイズ比率（data_to_file_cache_size_ratio）に基づくリストア最適化

## セキュリティ考慮事項

- リストア操作にはcluster:admin/snapshot/restore権限が必要
- リストアされるインデックスのセキュリティ設定は元のスナップショットの設定が適用される
- index_settingsパラメータでセキュリティ関連設定を上書き可能

## 備考

- RestoreServiceはClusterStateApplierを実装し、クラスタ状態変更を監視
- USER_UNMODIFIABLE_SETTINGSとUSER_UNREMOVABLE_SETTINGSにより、リストア時に変更・削除できない設定がある
- リモートストアバックドインデックスのリストアはsource_remote_store_repositoryパラメータで制御

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | RestoreInfo.java | `server/src/main/java/org/opensearch/snapshots/RestoreInfo.java` | リストア結果のデータ構造 |
| 1-2 | RestoreInProgress.java | `server/src/main/java/org/opensearch/cluster/RestoreInProgress.java` | クラスタ状態に保持されるリストア進行状況 |

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestoreService.java | `server/src/main/java/org/opensearch/snapshots/RestoreService.java` | リストアサービスの全体構造 |

**主要処理フロー**:
1. **133-154行目**: クラスのJavadoc - リストア処理の複数段階の説明
2. **155行目**: RestoreServiceクラス宣言、ClusterStateApplierを実装
3. **159-161行目**: USER_UNMODIFIABLE_SETTINGS - ユーザーが変更不可の設定
4. **164-174行目**: USER_UNREMOVABLE_SETTINGS - ユーザーが削除不可の設定
5. **176-198行目**: 主要依存関係の宣言

#### Step 3: シャードリカバリを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | RecoverySource.java | `server/src/main/java/org/opensearch/cluster/routing/RecoverySource.java` | SnapshotRecoverySourceの定義 |

### プログラム呼び出し階層図

```
REST API (POST /_snapshot/{repo}/{snap}/_restore)
    |
    +-- TransportRestoreSnapshotAction
            |
            +-- RestoreService.restoreSnapshot()
                    |
                    +-- Repository.getSnapshotInfo()
                    +-- Repository.getSnapshotIndexMetadata()
                    +-- ClusterStateUpdateTask
                    |       +-- インデックスメタデータ復元
                    |       +-- RoutingTable更新 (addAsRestore)
                    |       +-- RestoreInProgress追加
                    |
                    +-- AllocationService.reroute()
                    +-- IndexShard.restoreFromRepository()
```

### データフロー図

```
[入力]                        [処理]                         [出力]

RestoreSnapshotRequest ──> RestoreService ──> クラスタ状態更新
                              |                  (RestoreInProgress)
リポジトリBlobStore ──────> メタデータ読取 ──> インデックス作成
                              |                  (IndexMetadata)
                              +──> シャードリカバリ ──> ローカルディスク
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestoreService.java | `server/src/main/java/org/opensearch/snapshots/RestoreService.java` | ソース | リストアサービスのメインクラス |
| RestoreInfo.java | `server/src/main/java/org/opensearch/snapshots/RestoreInfo.java` | ソース | リストア結果情報 |
| RestoreInProgress.java | `server/src/main/java/org/opensearch/cluster/RestoreInProgress.java` | ソース | リストア進行状況 |
| SnapshotRecoverySource | `server/src/main/java/org/opensearch/cluster/routing/RecoverySource.java` | ソース | スナップショットリカバリソース |
| SnapshotsService.java | `server/src/main/java/org/opensearch/snapshots/SnapshotsService.java` | ソース | スナップショット管理（関連） |
| RepositoriesService.java | `server/src/main/java/org/opensearch/repositories/RepositoriesService.java` | ソース | リポジトリ管理（関連） |
