# 機能設計書 121-セグメント情報

## 概要

本ドキュメントは、OpenSearchにおけるLuceneセグメントの詳細情報を取得する「セグメント情報」機能の設計を記載する。

### 本機能の処理概要

本機能は、指定されたインデックスの各シャードに含まれるLuceneセグメントの低レベル情報を取得し返却する機能である。

**業務上の目的・背景**：Luceneインデックスは複数のセグメントで構成されており、セグメント数やサイズはインデックスの検索パフォーマンスやストレージ効率に直接影響する。運用者がセグメントの状態を把握し、フォースマージの必要性を判断したり、パフォーマンス問題の原因調査を行うために本機能が必要となる。

**機能の利用シーン**：インデックスのパフォーマンス分析、セグメントマージの効果確認、ストレージ使用量の調査、インデックスの健全性確認、デバッグ目的での低レベル情報の取得時に利用される。

**主要な処理内容**：
1. REST APIリクエストを受信し、対象インデックスを解決する
2. 全アクティブシャードに対してブロードキャストリクエストを送信する
3. 各シャードからLuceneセグメント情報を収集する
4. セグメント情報をインデックス別・シャード別に集約してレスポンスを構築する

**関連システム・外部連携**：Luceneライブラリのセグメント情報APIを内部で使用する。Cat Segments APIやPIT Segments APIとも連携する。

**権限による制御**：METADATA_READレベルのクラスタブロックチェックが行われ、メタデータ読み取りがブロックされている場合はリクエストが拒否される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 85 | セグメント情報 | 主機能 | Luceneインデックスのセグメント情報を返す処理 |
| 160 | Cat セグメント | 主機能 | シャード内セグメントの低レベル情報をテーブル形式で返す処理 |
| 166 | Cat PITセグメント | 補助機能 | セグメント情報の取得処理 |

## 機能種別

データ参照（SELECT相当）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| index | String[] | No | 対象インデックス名（省略時は全インデックス） | ワイルドカード対応 |
| verbose | boolean | No | 詳細情報を返すかどうか（デフォルト: false） | true/false |

### 入力データソース

REST APIリクエスト（`GET /<index>/_segments`）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| indices | Object | インデックス別のセグメント情報 |
| shards | Object | シャード別のセグメント詳細 |
| routing.state | String | シャードの状態 |
| routing.primary | boolean | プライマリシャードかどうか |
| routing.node | String | シャードが配置されているノードID |
| num_committed_segments | int | コミット済みセグメント数 |
| num_search_segments | int | 検索対象セグメント数 |
| segments.generation | long | セグメント世代番号 |
| segments.num_docs | int | セグメント内ドキュメント数 |
| segments.deleted_docs | int | セグメント内削除済みドキュメント数 |
| segments.size_in_bytes | long | セグメントサイズ（バイト） |
| segments.committed | boolean | コミット済みか |
| segments.search | boolean | 検索対象か |
| segments.version | String | Luceneバージョン |
| segments.compound | boolean | 複合ファイル形式か |

### 出力先

REST APIレスポンス（JSON形式）

## 処理フロー

### 処理シーケンス

```
1. REST APIリクエスト受信
   └─ IndicesSegmentsRequestを生成
2. クラスタブロックチェック
   └─ METADATA_READレベルのグローバル・インデックスブロックを確認
3. 対象シャードの決定
   └─ concreteIndicesの全シャード（プライマリ＋レプリカ）を取得
4. ブロードキャスト実行
   └─ 各ノードの各シャードに対してshardOperationを実行
5. シャード操作実行
   └─ IndexShard.segments()でLuceneセグメント情報を取得
6. レスポンス集約
   └─ ShardSegments配列をインデックス別にグルーピングしてIndicesSegmentResponseを生成
```

### フローチャート

```mermaid
flowchart TD
    A[REST API リクエスト受信] --> B{クラスタブロックチェック}
    B -->|ブロックあり| C[ClusterBlockException]
    B -->|OK| D[対象インデックスのシャード一覧取得]
    D --> E[各ノードへブロードキャストリクエスト送信]
    E --> F[各シャードでsegments取得]
    F --> G[ShardSegments生成]
    G --> H[全シャード結果をIndicesSegmentResponseに集約]
    H --> I[JSON形式でレスポンス返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 全シャード対象 | プライマリとレプリカの両方のシャードからセグメント情報を取得する | 常時 |
| BR-002 | verboseモード | verbose=trueの場合、追加の詳細情報が含まれる | verbose指定時 |
| BR-003 | ソート順 | レスポンスはインデックス名でソートされる | 常時 |

### 計算ロジック

- `num_committed_segments`: 各シャードのセグメントリストからisCommitted()=trueのものをカウント
- `num_search_segments`: 各シャードのセグメントリストからisSearch()=trueのものをカウント

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| セグメント情報取得 | Luceneインデックス | SELECT | 各シャードのLuceneセグメント情報を読み取る |

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

本機能はLuceneの内部APIを通じてセグメント情報を読み取る。RDBMSのテーブル操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ClusterBlockException | ブロック例外 | METADATA_READレベルのブロックが設定されている場合 | ブロック解除後に再試行 |
| IndexNotFoundException | インデックス未検出 | 指定されたインデックスが存在しない場合 | インデックス名を確認 |
| ShardOperationFailedException | シャード操作失敗 | 個別シャードでの情報取得に失敗した場合 | 部分的成功として処理される |

### リトライ仕様

リトライ機能は実装されていない。シャード単位の失敗はshardFailuresとしてレスポンスに含まれる。

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

読み取り専用操作のためトランザクション管理は不要。

## パフォーマンス要件

ブロードキャストリクエストのため、大規模クラスタでは全ノードへの通信が発生する。MANAGEMENTスレッドプールで実行される。

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

METADATA_READレベルのクラスタブロックチェックにより、メタデータアクセスが制限されている環境ではリクエストが拒否される。

## 備考

PIT（Point in Time）のセグメント情報取得用にPitSegmentsAction/TransportPitSegmentsActionも同パッケージに含まれている。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ShardSegments.java | `server/src/main/java/org/opensearch/action/admin/indices/segments/ShardSegments.java` | シャード単位のセグメント情報を保持するデータ構造。ShardRoutingとSegmentリストを内包 |
| 1-2 | IndexSegments.java | `server/src/main/java/org/opensearch/action/admin/indices/segments/IndexSegments.java` | インデックス単位でShardSegmentsをグルーピングするデータ構造 |
| 1-3 | Segment.java | `server/src/main/java/org/opensearch/index/engine/Segment.java` | Luceneセグメントの各属性（世代、ドキュメント数、サイズ等）を表現するクラス |

**読解のコツ**: ShardSegmentsはIterable<Segment>を実装しており、forループでセグメントを列挙可能。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | IndicesSegmentsAction.java | `server/src/main/java/org/opensearch/action/admin/indices/segments/IndicesSegmentsAction.java` | アクション定義（NAME="indices:monitor/segments"） |
| 2-2 | IndicesSegmentsRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/segments/IndicesSegmentsRequest.java` | リクエストクラス。verbose フラグを保持 |

**主要処理フロー**:
1. **51行目**: verboseフラグのデフォルトはfalse
2. **62-64行目**: インデックス名配列を受け取るコンストラクタ

#### Step 3: トランスポートアクションを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TransportIndicesSegmentsAction.java | `server/src/main/java/org/opensearch/action/admin/indices/segments/TransportIndicesSegmentsAction.java` | ブロードキャスト型アクションの実装。各シャードでセグメント取得を実行 |

**主要処理フロー**:
- **92-94行目**: shards()メソッドで全アクティブシャード（プライマリ＋レプリカ）を対象にする
- **97-98行目**: グローバルブロックチェック（METADATA_READ）
- **102-104行目**: インデックスレベルのブロックチェック
- **136-140行目**: shardOperation()でIndexShard.segments()を呼び出しShardSegmentsを生成

#### Step 4: レスポンス構築を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | IndicesSegmentResponse.java | `server/src/main/java/org/opensearch/action/admin/indices/segments/IndicesSegmentResponse.java` | レスポンスのJSON構築ロジック。セグメントの各属性をXContent形式で出力 |

**主要処理フロー**:
- **83-108行目**: getIndices()でShardSegments配列をインデックス名でソート・グルーピング
- **117-180行目**: addCustomXContentFields()でJSON構造を構築

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

```
REST Handler (RestIndicesSegmentsAction)
    |
    +-- TransportIndicesSegmentsAction
            |
            +-- shards() : 対象シャード一覧取得
            |
            +-- shardOperation() : 各シャードで実行
            |       |
            |       +-- IndicesService.indexServiceSafe()
            |       +-- IndexService.getShard()
            |       +-- IndexShard.segments(verbose)
            |       +-- new ShardSegments(routingEntry, segments)
            |
            +-- newResponse() : レスポンス集約
                    |
                    +-- new IndicesSegmentResponse(shards, ...)
                            |
                            +-- getIndices() : インデックス別グルーピング
```

### データフロー図

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

REST Request     -->  TransportBroadcastByNodeAction  -->  IndicesSegmentResponse
(index, verbose)      各シャードで                          (JSON)
                      IndexShard.segments()
                      を呼び出し
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| IndicesSegmentsAction.java | `server/src/main/java/org/opensearch/action/admin/indices/segments/` | ソース | アクション定義 |
| IndicesSegmentsRequest.java | 同上 | ソース | リクエストクラス |
| IndicesSegmentResponse.java | 同上 | ソース | レスポンスクラス・JSON構築 |
| TransportIndicesSegmentsAction.java | 同上 | ソース | トランスポートアクション実装 |
| ShardSegments.java | 同上 | ソース | シャード単位セグメントデータ |
| IndexSegments.java | 同上 | ソース | インデックス単位セグメントデータ |
| IndexShardSegments.java | 同上 | ソース | シャードID単位のセグメントグルーピング |
| PitSegmentsAction.java | 同上 | ソース | PIT用セグメント取得アクション |
| TransportPitSegmentsAction.java | 同上 | ソース | PIT用トランスポートアクション |
| Segment.java | `server/src/main/java/org/opensearch/index/engine/` | ソース | Luceneセグメント情報モデル |
