# バッチ設計書 7-AsyncRetentionLeaseSyncTask

## 概要

本ドキュメントは、OpenSearchのインデックスサービスにおけるリテンションリースの定期同期バッチタスクの設計を記載する。

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

AsyncRetentionLeaseSyncTaskは、プライマリシャードのリテンションリース情報をレプリカシャードに定期的に同期するバッチタスクである。

**業務上の目的・背景**：リテンションリースは、特定のシーケンス番号以降の操作履歴をトランスログに保持するための仕組みである。クロスクラスタレプリケーション（CCR）やシャードリカバリにおいて、必要な操作履歴がトリムされないよう保護するために使用される。本バッチは、プライマリシャードで管理されるリテンションリース情報をレプリカに定期的に同期し、フェイルオーバー時のデータ整合性を保証する。

**バッチの実行タイミング**：`index.soft_deletes.retention_lease.sync_interval`（デフォルト30秒）の間隔で定期実行される。インジェスションソースエンジンを使用するインデックスでは無効化される。

**主要な処理内容**：
1. インデックス内の全シャードを走査する
2. アクティブなプライマリシャードを特定する
3. STARTED状態のシャードに対して`syncRetentionLeases()`を呼び出す
4. リテンションリース情報がレプリカに同期される

**前後の処理との関連**：AsyncGlobalCheckpointTask（No.6）とともにレプリケーション整合性の維持に寄与する。リテンションリースはAsyncTrimTranslogTask（No.5）によるトランスログトリムの範囲を制限する。

**影響範囲**：プライマリシャードとレプリカシャード間のリテンションリース整合性に影響する。トランスログの保持範囲に間接的に影響する。

## バッチ種別

データ同期処理（リテンションリースの同期）

## 実行スケジュール

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

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| IndexServiceが未クローズ | `indexService.closed.get() == false`であること |
| インデックスがOPEN状態 | `IndexMetadata.State.OPEN`であること |
| インジェスションソースではない | `indexSettings.getIndexMetadata().useIngestionSource()`がfalseであること |
| シャードがアクティブなプライマリ | `routingEntry().active()`かつ`routingEntry().primary()`であること |
| シャードがSTARTED状態 | `shard.state() == STARTED`であること |

### 実行可否判定

BaseAsyncTaskの`mustReschedule()`により標準的な条件チェックが行われる。実際の同期処理は`sync()`ヘルパーメソッド内で、アクティブかつプライマリかつSTARTED状態のシャードに対してのみ実行される。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| index.soft_deletes.retention_lease.sync_interval | TimeValue | No | 30s | リテンションリース同期の実行間隔 |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| IndexServiceのシャードマップ | インメモリ | 対象インデックスに属する全シャード |
| プライマリシャードのリテンションリース | インメモリ | 現在有効なリテンションリースの一覧 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| リテンションリース | インメモリ/ネットワーク | 更新されたリテンションリース情報がレプリカに伝達される |

### 出力ファイル仕様

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

## 処理フロー

### 処理シーケンス

```
1. タイマーによる定期起動
   └─ AbstractAsyncTaskにより30秒間隔で起動
2. シャード走査
   └─ 全シャードをイテレーション
3. 対象シャード判定
   └─ active かつ primary かつ STARTED状態のシャードを特定
4. リテンションリース同期
   └─ IndexShard::syncRetentionLeases を呼び出し
5. 次回スケジュール
   └─ mustReschedule()がtrueの場合、再スケジュール
```

### フローチャート

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

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

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

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| リテンションリース同期 | リテンションリースメタデータ | UPDATE | プライマリからレプリカへのリテンションリース同期 |

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

#### リテンションリースメタデータ

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | リテンションリース一覧 | プライマリシャードの現在のリテンションリース | RetentionLeaseSyncAction経由で同期 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | AlreadyClosedException | シャードが既にクローズされている | 例外をキャッチして処理を継続 |
| - | Exception | リテンションリース同期時の一般的なエラー | 警告ログを出力して処理を継続 |

### リトライ仕様

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

### 障害時対応

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

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

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

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | プライマリシャード数に依存 |
| 目標処理時間 | sync_interval内に完了すること |
| メモリ使用量上限 | 追加メモリ使用なし |

## 排他制御

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

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 警告ログ | 同期失敗時 | "failed to sync retention lease" + 例外情報 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| リテンションリース同期遅延 | レプリカとのリテンションリース差 | OpenSearchログ（WARN） |

## 備考

- 本タスクはMANAGEMENTスレッドプールで実行される（他のタスクとは異なるスレッドプール）
- `index.soft_deletes.retention_lease.sync_interval`は正式に登録されたSettingではなく、テスト用途でも使用される
- インジェスションソースエンジンを使用するインデックスでは本タスクは作成されない
- RetentionLeaseSyncAction（`server/src/main/java/org/opensearch/index/seqno/RetentionLeaseSyncAction.java`）およびRetentionLeaseBackgroundSyncAction（`server/src/main/java/org/opensearch/index/seqno/RetentionLeaseBackgroundSyncAction.java`）が実際の同期ロジックを実装する
- ソースコード: `server/src/main/java/org/opensearch/index/IndexService.java` (AsyncRetentionLeaseSyncTask内部クラス)
