# バッチ設計書 4-AsyncPublishReferencedSegmentsTask

## 概要

本ドキュメントは、OpenSearchのプライマリシャードが参照しているセグメント情報を定期的に公開するバッチタスクの設計を記載する。

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

AsyncPublishReferencedSegmentsTaskは、セグメントレプリケーションまたはリモートストアが有効なインデックスにおいて、プライマリシャードの参照セグメント情報を定期的に公開するバッチタスクである。これにより、レプリカシャードは不要なマージ中セグメントを適切にクリーンアップできる。

**業務上の目的・背景**：セグメントレプリケーション環境では、プライマリシャードでマージが実行されると新しいセグメントが生成され、古いセグメントが不要になる。レプリカシャードが不要なマージ中セグメントを安全にクリーンアップするためには、プライマリシャードが現在参照しているセグメントの情報を知る必要がある。本バッチはこの情報を定期的に公開する。

**バッチの実行タイミング**：`index.segrep.publish_referenced_segments_interval`で設定可能な間隔で定期実行される。セグメントレプリケーションまたはリモートストアが有効で、かつマージ済みセグメントレプリケーションウォーマーが有効な場合のみ実行される。

**主要な処理内容**：
1. セグメントレプリケーションまたはリモートストアが有効か確認する
2. マージ済みセグメントレプリケーションウォーマーが有効か確認する
3. インデックス内の全シャードを走査する
4. プライマリモードかつアクティブなシャードに対して参照セグメント情報を公開する

**前後の処理との関連**：AsyncReplicationTask（No.3）と連携し、レプリカへのセグメントレプリケーションを補完する。プライマリシャードのリフレッシュ・マージ処理の後に参照セグメント情報が更新される。

**影響範囲**：プライマリシャードの参照セグメントメタデータに影響する。レプリカシャードの不要セグメントクリーンアップに間接的に影響する。

## バッチ種別

メタデータ同期処理（セグメント参照情報の公開）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 定期実行（設定可能な間隔） |
| 実行時刻 | インデックスのライフサイクルに依存（常時） |
| 実行曜日 | 該当なし（常時稼働） |
| 実行日 | 該当なし（常時稼働） |
| トリガー | タイマーベースの定期スケジュール（AbstractAsyncTask） |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| IndexServiceが未クローズ | `indexService.closed.get() == false`であること |
| インデックスがOPEN状態 | `IndexMetadata.State.OPEN`であること |
| セグレプまたはリモートストア有効 | `indexSettings.isSegRepEnabledOrRemoteNode()`がtrueであること |
| セグレプローカルまたはリモートストア有効 | `indexSettings.isSegRepLocalEnabled() \|\| indexSettings.isRemoteStoreEnabled()`がtrueであること |
| マージセグメントウォーマー有効 | `recoverySettings.isMergedSegmentReplicationWarmerEnabled()`がtrueであること |

### 実行可否判定

`mustReschedule()`で`isSegRepEnabledOrRemoteNode()`を確認し、さらに`shouldRun()`で`isSegRepLocalEnabled()`または`isRemoteStoreEnabled()`かつ`isMergedSegmentReplicationWarmerEnabled()`を確認する。全条件を満たす場合のみ処理が実行される。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| index.segrep.publish_referenced_segments_interval | TimeValue | No | （IndexSettingsで定義） | 参照セグメント公開の実行間隔 |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| IndexServiceのシャードマップ | インメモリ | 対象インデックスに属する全シャード |
| プライマリシャードのセグメント情報 | インメモリ | 現在参照しているセグメントの一覧 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 参照セグメントメタデータ | インメモリ/ネットワーク | プライマリが参照しているセグメント情報がレプリカに伝達される |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | 該当なし（メタデータの公開） |
| 出力先 | レプリカシャードへのメタデータ伝達 |
| 文字コード | 該当なし |
| 区切り文字 | 該当なし |

## 処理フロー

### 処理シーケンス

```
1. タイマーによる定期起動
   └─ AbstractAsyncTaskにより指定間隔で起動
2. 実行条件チェック（shouldRun）
   └─ セグレプ/リモートストア有効、ウォーマー有効を確認
3. シャード走査
   └─ 全シャードをイテレーション
4. プライマリシャード判定
   └─ isPrimaryMode() かつ active なシャードを特定
5. 参照セグメント公開
   └─ shard.publishReferencedSegments()を呼び出し
6. 次回スケジュール
   └─ mustReschedule()がtrueの場合、再スケジュール
```

### フローチャート

```mermaid
flowchart TD
    A[タイマー起動] --> B{shouldRun?}
    B -->|No| G[処理スキップ]
    B -->|Yes| C[全シャード走査開始]
    C --> D{次のシャードあり?}
    D -->|No| H[処理終了・再スケジュール]
    D -->|Yes| E{プライマリ かつ active?}
    E -->|No| D
    E -->|Yes| F[publishReferencedSegments 実行]
    F --> D
    G --> H
```

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

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

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| セグメント情報公開 | セグメントメタデータ | READ/PUBLISH | プライマリシャードの参照セグメント情報を公開 |

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

#### セグメントメタデータ

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| PUBLISH | 参照セグメント一覧 | プライマリシャードが現在参照しているセグメント | レプリカの不要セグメントクリーンアップに使用 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | IOException | セグメント情報公開時のI/Oエラー | 警告ログを出力して処理を継続（次のシャードへ） |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 明示的なリトライなし（次回スケジュール実行で再試行） |
| リトライ間隔 | publish_referenced_segments_interval |
| リトライ対象エラー | IOException（次回実行時に自動的に再試行） |

### 障害時対応

セグメント情報の公開に失敗した場合、警告ログが出力され次のシャードの処理に進む。次回スケジュール実行時に再度公開が試行される。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | シャード単位（各シャードの公開は独立） |
| コミットタイミング | 公開処理完了時 |
| ロールバック条件 | 該当なし |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | プライマリシャード数に依存 |
| 目標処理時間 | 設定された間隔内に完了すること |
| メモリ使用量上限 | セグメントメタデータのサイズに依存 |

## 排他制御

同一インデックスに対するAsyncPublishReferencedSegmentsTaskは1つのみ存在する。各シャードのpublishReferencedSegments()は内部で適切な排他制御を行う。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 警告ログ | セグメント情報公開失敗時 | "failed to publish primary referenced segments" + 例外情報 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 公開エラー | 継続的なIOException発生 | OpenSearchログ（WARN） |

## 備考

- 本タスクはGENERICスレッドプールで実行される
- セグメントレプリケーションまたはリモートストアが無効な場合、`mustReschedule()`がfalseを返し、タスクは自動的に停止する
- `shouldRun()`メソッドはテスト用に可視性が設定されている
- レプリカはプライマリからの参照セグメント情報に基づいて、不要なマージ中（pending merge）セグメントをクリーンアップする
- ソースコード: `server/src/main/java/org/opensearch/index/IndexService.java` (AsyncPublishReferencedSegmentsTask内部クラス)
