# 画面設計書 47-インデックス分割

## 概要

本ドキュメントは、OpenSearchのインデックス分割API（PUT/POST /{index}/_split/{target}）の設計仕様を記述する。

### 本画面の処理概要

本APIは、既存のインデックスをプライマリシャード数の多い新しいインデックスに分割するためのエンドポイントである。

**業務上の目的・背景**：データ量が増加してシャードあたりのデータ量が過大になった場合、より多くのシャードに分散させることで検索パフォーマンスを改善できる。当初の設計よりもデータ量が増加した場合のスケールアウト手段として使用する。分割先のシャード数はソースシャード数の倍数でなければならない。縮小操作とは逆方向のリサイズ操作である。

**画面へのアクセス方法**：`PUT /{index}/_split/{target}` または `POST /{index}/_split/{target}` エンドポイントにHTTPリクエストを送信する。

**主要な操作・処理内容**：
1. クライアントがPUT/POSTリクエストでソースインデックス名とターゲットインデックス名を指定して送信する
2. RestResizeHandler.RestSplitIndexAction がリクエストを処理し、ResizeRequestを構築する
3. ResizeType.SPLITが設定される
4. オプションでリクエストボディにsettingsとaliasesを指定可能
5. クラスタマネージャノードで分割処理が実行される
6. 非同期実行（wait_for_completion=false）の場合、タスクIDが即時返却される
7. 処理結果（acknowledged, shards_acknowledged, index）をレスポンスとして返す

**画面遷移**：インデックス作成（PUT /{index}）で作成されたインデックスを分割する。分割先は新しいインデックスとして作成される。前提条件として、ソースインデックスが読み取り専用に設定されている必要がある。

**権限による表示制御**：インデックスの管理権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | インデックスシュリンク/スプリット | 主機能 | 既存インデックスをプライマリシャードの多い新インデックスに分割する処理 |

## 画面種別

実行（インデックス分割作成）

## URL/ルーティング

| メソッド | パス | 説明 |
|----------|------|------|
| PUT | `/{index}/_split/{target}` | インデックスの分割 |
| POST | `/{index}/_split/{target}` | インデックスの分割 |

## 入出力項目

### パスパラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|------|------|------|
| index | string | はい | ソースインデックス名 |
| target | string | はい | ターゲットインデックス名 |

### クエリパラメータ

| パラメータ名 | 型 | デフォルト | 説明 |
|-------------|------|-----------|------|
| copy_settings | boolean | false | ソースインデックスから設定をコピーするか（非推奨） |
| timeout | time | 30s | 操作タイムアウト |
| cluster_manager_timeout | time | 30s | クラスタマネージャノードへの接続タイムアウト |
| master_timeout | time | - | 非推奨（cluster_manager_timeoutを使用） |
| wait_for_active_shards | string | - | アクティブシャードの待機数 |
| wait_for_completion | boolean | true | falseの場合、タスクを即時返却しバックグラウンド実行 |
| task_execution_timeout | time | 1h | タスク実行タイムアウト（wait_for_completion=false時のみ有効） |

### リクエストボディ（任意）

| フィールド | 型 | 説明 |
|-----------|------|------|
| settings | object | ターゲットインデックスの設定（number_of_shards等） |
| aliases | object | ターゲットインデックスのエイリアス |

## 表示項目

### 同期レスポンス（wait_for_completion=true）

| 項目名 | 型 | 説明 |
|--------|------|------|
| acknowledged | boolean | クラスタ状態の更新が認識されたか |
| shards_acknowledged | boolean | 指定数のシャードコピーが開始されたか |
| index | string | 作成されたインデックス名 |

### 非同期レスポンス（wait_for_completion=false）

| 項目名 | 型 | 説明 |
|--------|------|------|
| task | string | タスクID |

## イベント仕様

### 1-インデックス分割リクエスト送信（同期）

RestResizeHandler.prepareRequest()（77-131行目）がリクエストを処理する。ResizeRequestを構築し、ResizeType.SPLITを設定する。処理の流れは縮小・クローンと共通である。

### 2-インデックス分割リクエスト送信（非同期）

wait_for_completion=falseの場合、タスクとして非同期実行する。

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| PUT /{index}/_split/{target} | ClusterState（メモリ） | INSERT | 分割された新インデックスのメタデータをクラスタ状態に追加 |

### テーブル別更新項目詳細

#### ClusterState.metadata.indices

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | IndexMetadata | ソースインデックスのデータを多いシャード数で再構成した新インデックス | ターゲット名で新規作成 |

## メッセージ仕様

| メッセージ種別 | 条件 | HTTPステータス | 内容 |
|--------------|------|---------------|------|
| 成功 | 分割が完了 | 200 | {"acknowledged": true, "shards_acknowledged": true, "index": "target_name"} |
| 成功（タスク） | 非同期実行開始 | 200 | {"task": "node_id:task_id"} |
| エラー | ソースインデックスが読み取り専用でない | 400 | illegal_state_exception |
| エラー | シャード数が倍数でない | 400 | illegal_argument_exception |

## 例外処理

| 例外 | 条件 | 動作 |
|------|------|------|
| IndexNotFoundException | ソースインデックスが存在しない | 404エラーを返す |
| IllegalStateException | ソースインデックスが読み取り専用でない | 400エラーを返す |
| IllegalArgumentException | ターゲットシャード数がソースの倍数でない | 400エラーを返す |
| ResourceAlreadyExistsException | ターゲットインデックスが既に存在 | 400エラーを返す |

## 備考

- ソースインデックスは事前に読み取り専用に設定されている必要がある。
- ターゲットのシャード数はソースのシャード数の倍数でなければならない（例: 5シャード -> 10, 15, 20...シャード）。
- RestResizeHandlerは共通の抽象クラスで、縮小・分割・クローンの3つを処理する。
- copy_settingsパラメータは非推奨（3.0.0で削除予定）。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ResizeRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/shrink/ResizeRequest.java` | resizeType、targetIndex等のフィールドを確認 |
| 1-2 | ResizeType.java | `server/src/main/java/org/opensearch/action/admin/indices/shrink/ResizeType.java` | SPLIT列挙値を確認 |

**読解のコツ**: 分割・縮小・クローンは全て同じResizeRequest/ResizeTypeを使用し、ResizeTypeで処理が分岐する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestResizeHandler.java | `server/src/main/java/org/opensearch/rest/action/admin/indices/RestResizeHandler.java` | 162-179行目: RestSplitIndexAction内部クラスの定義 |

**主要処理フロー**:
1. **165-166行目**: `PUT/POST /{index}/_split/{target}` のルート登録
2. **175-176行目**: getResizeType()がResizeType.SPLITを返す
3. **77-131行目**: 共通のprepareRequest()でResizeRequest構築・実行

#### Step 3: Transport層の処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TransportResizeAction.java | `server/src/main/java/org/opensearch/action/admin/indices/shrink/TransportResizeAction.java` | リサイズ処理の共通ロジック |

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

```
RestResizeHandler.RestSplitIndexAction
    |
    +-- RestResizeHandler.prepareRequest()
            |
            +-- ResizeRequest(target, index)
            +-- setResizeType(ResizeType.SPLIT)
            |
            +-- [wait_for_completion=true]
            |       +-- NodeClient.admin().indices().resizeIndex()
            |               +-- TransportResizeAction
            |
            +-- [wait_for_completion=false]
                    +-- NodeClient.executeLocally(ResizeAction.INSTANCE, ...)
```

### データフロー図

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

PUT /{index}/_split/{target}   RestResizeHandler.RestSplitIndexAction  JSON レスポンス
  +                                  |                                {acknowledged: true,
  ソースindex名                 ResizeRequest構築                       shards_acknowledged: true,
  ターゲットindex名             (type=SPLIT)                            index: "target"}
  settings(任意)                      |
                              TransportResizeAction
                                     |
                              シャード分割処理
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| indices.split.json | `rest-api-spec/src/main/resources/rest-api-spec/api/indices.split.json` | API定義 | REST APIスペック定義 |
| RestResizeHandler.java | `server/src/main/java/org/opensearch/rest/action/admin/indices/RestResizeHandler.java` | ソース | RESTハンドラ（共通基底 + RestSplitIndexAction内部クラス） |
| ResizeRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/shrink/ResizeRequest.java` | ソース | リクエストデータ構造 |
| ResizeType.java | `server/src/main/java/org/opensearch/action/admin/indices/shrink/ResizeType.java` | ソース | リサイズ種別列挙型 |
| TransportResizeAction.java | `server/src/main/java/org/opensearch/action/admin/indices/shrink/TransportResizeAction.java` | ソース | Transport層処理 |
