# 機能設計書 178-Join-DbaAvailabilityGroup

## 概要

本ドキュメントは、dbatools PowerShellモジュールのJoin-DbaAvailabilityGroup関数の機能設計を定義する。SQL Serverインスタンスを既存の可用性グループにセカンダリレプリカとして追加する機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：可用性グループはSQL Serverの高可用性・災害復旧ソリューションの中核を成す。この関数は、プライマリサーバーで既に作成された可用性グループに、セカンダリレプリカとしてSQL Serverインスタンスを追加するために使用される。通常、New-DbaAvailabilityGroupでプライマリに可用性グループを作成した後、Add-DbaAgDatabaseでデータベースを追加する前に使用される。

**機能の利用シーン**：
- 可用性グループのセットアップ時のセカンダリレプリカ追加
- 既存の可用性グループへの新規セカンダリ追加
- 災害復旧サイトの構築
- 読み取り可能セカンダリの追加

**主要な処理内容**：
1. 入力パラメータの検証（SqlInstance/InputObject必須）
2. InputObjectから可用性グループ名とClusterType取得（指定時）
3. 各インスタンスへの接続
4. SQL Server 2017以降の場合、ClusterType指定でALTER AVAILABILITY GROUP ... JOIN実行
5. 従来のSQL Serverの場合、SMO JoinAvailabilityGroup()メソッド呼び出し

**関連システム・外部連携**：Windows Server Failover Clustering (WSFC)、または外部クラスターマネージャー（Pacemaker等）との連携。

**権限による制御**：ALTER AVAILABILITY GROUP権限またはCONTROL AVAILABILITY GROUP権限が必要。HADR機能が有効化されている必要がある。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | 可用性グループ管理 | 補助機能 | 既存の可用性グループへのセカンダリレプリカ追加 |

## 機能種別

可用性グループ管理 / 高可用性設定

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | ターゲットSQL Serverインスタンス | SQL Server 2012以上 |
| SqlCredential | PSCredential | No | 接続資格情報 | - |
| AvailabilityGroup | string[] | No | 参加する可用性グループ名 | - |
| ClusterType | string | No | クラスタータイプ（SQL 2017+） | ValidateSet: External, Wsfc, None |
| InputObject | AvailabilityGroup[] | No | パイプラインからの可用性グループオブジェクト | ValueFromPipeline |
| EnableException | switch | No | 例外をスローするか | - |

### 入力データソース

- SqlInstanceパラメータで指定されたSQL Serverインスタンス
- Get-DbaAvailabilityGroupからパイプラインで渡される可用性グループオブジェクト

## 出力仕様

### 出力データ

なし（設定操作のみ）

### 出力先

- 成功時は出力なし
- エラー時はStop-Functionでエラーメッセージ出力

## 処理フロー

### 処理シーケンス

```
1. パラメータ検証
   ├─ SqlInstanceまたはInputObjectの指定確認
   └─ AvailabilityGroupの指定確認

2. InputObject処理（指定時）
   ├─ 可用性グループ名を追加
   └─ ClusterType未指定時はInputObjectから取得

3. 各インスタンスに対する処理
   ├─ Connect-DbaInstance接続
   └─ 各可用性グループに対してJoin実行

4. Join実行
   ├─ SQL Server 2017+かつClusterType指定時
   │   └─ ALTER AVAILABILITY GROUP [name] JOIN WITH (CLUSTER_TYPE = type)
   └─ それ以外
       └─ server.JoinAvailabilityGroup(name)
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{SqlInstance or<br/>InputObject?}
    B -->|どちらも未指定| C[エラー: パラメータ必須]
    B -->|指定あり| D{InputObject<br/>指定?}
    D -->|Yes| E[AG名とClusterType取得]
    D -->|No| F{AvailabilityGroup<br/>指定?}
    E --> F
    F -->|No| G[エラー: AG名必須]
    F -->|Yes| H{インスタンスループ}
    H -->|次のInstance| I[Connect-DbaInstance]
    I --> J{接続成功?}
    J -->|No| K[エラー出力]
    K --> H
    J -->|Yes| L{AGループ}
    L -->|次のAG| M{ShouldProcess?}
    M -->|No| L
    M -->|Yes| N{SQL 2017+かつ<br/>ClusterType指定?}
    N -->|Yes| O[ALTER AVAILABILITY GROUP<br/>JOIN WITH CLUSTER_TYPE]
    N -->|No| P[JoinAvailabilityGroup<br/>メソッド呼び出し]
    O --> Q{成功?}
    P --> Q
    Q -->|No| R[エラー出力]
    Q -->|Yes| L
    R --> L
    L -->|完了| H
    H -->|完了| S[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-178-01 | SQL Server 2012以上 | SQL Server 2012以上が必要 | 常時 |
| BR-178-02 | ClusterType自動取得 | InputObject使用時、ClusterTypeは自動取得可能 | InputObject指定時 |
| BR-178-03 | SQL 2017+ ClusterType | SQL Server 2017以降でClusterType指定時はALTER構文使用 | VersionMajor >= 14 かつ ClusterType指定時 |
| BR-178-04 | HADR有効化必須 | インスタンスのHADR機能が有効化されている必要 | 常時 |

### 計算ロジック

SQL Server 2017判定:
```powershell
if ($ClusterType -and $server.VersionMajor -ge 14) {
    # ALTER AVAILABILITY GROUP構文を使用
}
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| JOIN実行 | sys.availability_groups | INSERT | 可用性グループメタデータ登録 |
| JOIN実行 | sys.availability_replicas | UPDATE | レプリカ情報登録 |

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

#### SQL Server 2017+ (ClusterType指定時)
```sql
ALTER AVAILABILITY GROUP [AGName] JOIN WITH (CLUSTER_TYPE = Wsfc)
```

#### 従来のSQL Server
SMO `JoinAvailabilityGroup()` メソッド呼び出し

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | MissingParameter | SqlInstanceとInputObjectが両方未指定 | いずれかを指定 |
| - | MissingParameter | AvailabilityGroupが未指定 | 可用性グループ名を指定 |
| - | ConnectionError | インスタンスへの接続失敗 | 接続情報を確認 |
| - | JoinError | JOIN操作失敗 | 権限・HADR設定を確認 |

### リトライ仕様

リトライ機能なし。エラー発生時はStop-Functionで処理を継続（-Continue）。

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

ALTER AVAILABILITY GROUP JOINは内部的にトランザクション管理される。

## パフォーマンス要件

- JOIN操作はほぼ即時完了
- ネットワーク接続確立に依存

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

- ALTER AVAILABILITY GROUP権限が必要
- SqlCredentialによる安全な認証をサポート
- Windows認証、SQL Server認証、Active Directory認証に対応

## 備考

- Get-DbaAvailabilityGroupと組み合わせてパイプライン操作可能
- 通常、New-DbaAvailabilityGroupの後、Add-DbaAgDatabaseの前に実行

---

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

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

### 推奨読解順序

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

パラメータとInputObjectの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Join-DbaAvailabilityGroup.ps1 | `public/Join-DbaAvailabilityGroup.ps1` | 84-93行目: パラメータ定義 |

**読解のコツ**: InputObjectがMicrosoft.SqlServer.Management.Smo.AvailabilityGroup[]型であることを理解する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Join-DbaAvailabilityGroup.ps1 | `public/Join-DbaAvailabilityGroup.ps1` | 関数全体の流れを把握 |

**主要処理フロー**:
1. **94-98行目**: SqlInstance/InputObject検証
2. **100-108行目**: InputObjectからAG名とClusterType取得
3. **110-113行目**: AvailabilityGroup検証
4. **115-120行目**: インスタンス接続
5. **122-133行目**: JOIN実行

#### Step 3: JOIN実行ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Join-DbaAvailabilityGroup.ps1 | `public/Join-DbaAvailabilityGroup.ps1` | 124-132行目: JOIN実行の分岐 |

**主要処理フロー**:
- **125-126行目**: SQL 2017+ ClusterType指定時のALTER構文
- **127-128行目**: 従来のJoinAvailabilityGroupメソッド

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

```
Join-DbaAvailabilityGroup
    │
    ├─ processブロック
    │      ├─ パラメータ検証
    │      │
    │      ├─ InputObject処理
    │      │      ├─ $InputObject.Name取得
    │      │      └─ $InputObject.ClusterType取得
    │      │
    │      └─ インスタンスループ
    │             ├─ Connect-DbaInstance
    │             │
    │             └─ AGループ
    │                    ├─ server.Query() (SQL 2017+)
    │                    │     └─ ALTER AVAILABILITY GROUP ... JOIN
    │                    │
    │                    └─ server.JoinAvailabilityGroup() (従来)
    │
    └─ エラー処理
           └─ Stop-Function
```

### データフロー図

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

Get-DbaAvailabilityGroup ─▶ InputObject
                                 │
                                 ▼
                          AG名/ClusterType取得
                                 │
SqlInstance ─────────────▶ Connect-DbaInstance
                                 │
                                 ▼
                    ┌────────────┴────────────┐
                    ▼                         ▼
              [SQL 2017+]              [SQL 2016以前]
              ClusterType指定                  │
                    │                         │
                    ▼                         ▼
            ALTER AVAILABILITY      JoinAvailabilityGroup()
            GROUP ... JOIN
                    │                         │
                    └────────────┬────────────┘
                                 ▼
                          セカンダリレプリカとして参加
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Join-DbaAvailabilityGroup.ps1 | `public/Join-DbaAvailabilityGroup.ps1` | ソース | メイン関数 |
| Get-DbaAvailabilityGroup.ps1 | `public/Get-DbaAvailabilityGroup.ps1` | ソース | AG情報取得（パイプライン入力元） |
| New-DbaAvailabilityGroup.ps1 | `public/New-DbaAvailabilityGroup.ps1` | ソース | AG作成（事前処理） |
| Add-DbaAgDatabase.ps1 | `public/Add-DbaAgDatabase.ps1` | ソース | AGデータベース追加（後続処理） |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続処理 |
