# 機能設計書 1-Add-DbaAgDatabase

## 概要

本ドキュメントは、dbatools PowerShellモジュールのAdd-DbaAgDatabase機能の設計仕様を定義する。本機能は、SQL Server可用性グループへのデータベース追加処理を自動化し、バックアップ、リストア、同期処理を一括して管理する。

### 本機能の処理概要

Add-DbaAgDatabaseは、SQL Server Always On可用性グループ(AG)に対してデータベースを追加するための包括的なPowerShellコマンドである。従来、可用性グループへのデータベース追加は複数の手動ステップ（バックアップ取得、セカンダリへのリストア、AGへの参加、同期確認）を必要としていたが、本機能はこれらすべてを自動化する。

**業務上の目的・背景**：SQL Server Always On可用性グループは、高可用性とディザスタリカバリを実現する重要な機能だが、新規データベースを追加する際の手順が複雑である。DBAは各セカンダリレプリカに対してバックアップのリストアを行い、データベースをAGに参加させ、同期状態を確認する必要がある。本機能は、これらの煩雑な手動作業を自動化することで、運用効率の向上と人的ミスの削減を実現する。

**機能の利用シーン**：
- 新規アプリケーションのデータベースを本番可用性グループに追加する場合
- 既存のスタンドアロンデータベースを高可用性構成に移行する場合
- SharePointなど複数データベースを持つアプリケーションの可用性グループ設定
- DR（ディザスタリカバリ）環境の構築・拡張時

**主要な処理内容**：
1. シーディングモードの設定（必要に応じてAutomatic/Manualに変更）
2. バックアップとリストアの実行（Manualシーディング時、セカンダリにDBが存在しない場合）
3. プライマリレプリカへのデータベースAG参加
4. セカンダリレプリカへのデータベースAG参加
5. 同期完了の待機と進捗監視

**関連システム・外部連携**：
- SQL Server SMO (Server Management Objects)
- Windows Server Failover Cluster (WSFC)
- 共有ストレージ（バックアップファイル用UNCパス）

**権限による制御**：
- プライマリレプリカでのsysadmin権限が必要
- セカンダリレプリカへの接続権限
- 共有パスへの読み書きアクセス権限（Manualシーディング時）
- Automaticシーディング時はCreateAnyDatabase権限が自動付与される

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | AGデータベース管理 | 主機能 | 可用性グループへのデータベース追加 |

## 機能種別

データ連携 / インフラストラクチャ管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter | Yes (NonPipeline) | プライマリレプリカのSQL Serverインスタンス | SQL Server 2012以上 |
| SqlCredential | PSCredential | No | SQL Server接続用の認証情報 | - |
| AvailabilityGroup | string | Yes | 対象の可用性グループ名 | 存在する必要あり |
| Database | string[] | Yes (NonPipeline) | 追加するデータベース名 | - |
| Secondary | DbaInstanceParameter[] | No | セカンダリレプリカインスタンス | 指定しない場合は自動検出 |
| SecondarySqlCredential | PSCredential | No | セカンダリ接続用の認証情報 | - |
| InputObject | Database[] | Yes (Pipeline) | パイプライン経由のデータベースオブジェクト | - |
| SeedingMode | string | No | シーディングモード（Automatic/Manual） | ValidateSet |
| SharedPath | string | No | バックアップ用UNCパス | Manualシーディング時に必要 |
| UseLastBackup | switch | No | 既存バックアップ履歴を使用 | - |
| AdvancedBackupParams | hashtable | No | Backup-DbaDatabase用追加パラメータ | - |
| NoWait | switch | No | 同期完了を待機しない | - |
| SkipReuseSourceFolderStructure | switch | No | ソースフォルダ構造を再利用しない | - |
| EnableException | switch | No | 例外を有効化 | - |

### 入力データソース

- SQL Serverインスタンスへの直接接続
- Get-DbaDatabase等からのパイプライン入力
- 可用性グループのメタデータ（SMO経由）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| AvailabilityGroup | string | 可用性グループ名 |
| LocalReplicaRole | string | レプリカの役割（Primary/Secondary） |
| Name | string | データベース名 |
| SynchronizationState | string | 同期状態 |
| IsFailoverReady | bool | フェイルオーバー準備完了か |
| IsJoined | bool | AGに参加済みか |
| IsSuspended | bool | データ移動が一時停止中か |

### 出力先

- PowerShellパイプライン（Microsoft.SqlServer.Management.Smo.AvailabilityDatabase型）
- 詳細ログ（Write-Messageによるverbose出力）
- 進捗バー（Write-Progressによる表示）

## 処理フロー

### 処理シーケンス

```
1. 前提条件テスト (Test-DbaAvailabilityGroup)
   └─ 各データベースについてAG追加の前提条件を検証

2. Step 1: シーディングモード設定
   └─ SeedingModeパラメータ指定時、レプリカのシーディングモードを変更
   └─ Automatic設定時はCreateAnyDatabase権限を付与

3. Step 2: バックアップとリストア（Manualシーディング時）
   └─ UseLastBackup: 既存バックアップ履歴を使用
   └─ それ以外: フル＋ログバックアップを取得しリストア

4. Step 3: プライマリへのデータベース追加
   └─ AvailabilityDatabaseオブジェクト作成
   └─ Create()メソッド実行
   └─ 状態がExistingになるまで待機

5. Step 4: セカンダリへのデータベース追加
   └─ 各セカンダリレプリカでJoinAvailablityGroup()実行
   └─ Automaticシーディングの場合は自動同期を待機

6. Step 5: 同期完了待機
   └─ NoWait指定時はスキップ
   └─ 各レプリカでSynchronizationStateを監視
   └─ 進捗バーで同期状態を表示
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[前提条件テスト]
    B --> C{テスト成功?}
    C -->|No| Z[エラー終了]
    C -->|Yes| D{SeedingMode指定?}
    D -->|Yes| E[シーディングモード設定]
    D -->|No| F{Manual + リストア必要?}
    E --> F
    F -->|Yes| G{UseLastBackup?}
    F -->|No| H[プライマリにDB追加]
    G -->|Yes| I[既存バックアップ使用]
    G -->|No| J[フル＋ログバックアップ取得]
    I --> K[セカンダリにリストア]
    J --> K
    K --> H
    H --> L[セカンダリにDB追加/Join]
    L --> M{NoWait?}
    M -->|Yes| N[即座に完了]
    M -->|No| O[同期完了待機]
    O --> P{同期完了?}
    P -->|No| Q[進捗表示]
    Q --> O
    P -->|Yes| N
    N --> R[結果出力]
    R --> S[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | SQLバージョン要件 | SQL Server 2012以上が必要 | 常時 |
| BR-02 | シーディングモード制御 | 変更後のモードは維持される | SeedingMode指定時 |
| BR-03 | クロスプラットフォーム検出 | Windows/Linux間でフォルダ構造再利用を自動スキップ | 異なるHostPlatform検出時 |
| BR-04 | 所有者保持 | ソースDB所有者がセカンダリに存在する場合、ExecuteAsで所有者を維持 | リストア時 |
| BR-05 | 同期状態判定 | SynchronousCommitはSynchronized、AsynchronousCommitはSynchronizing | 待機時 |

### 計算ロジック

- 同期進捗率: `transferred_size_bytes * 100.0 / database_size_bytes`
- 残り時間: `estimate_time_complete_utc - 現在UTC時刻`

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| シーディング状態取得 | sys.dm_hadr_physical_seeding_stats | SELECT | 物理シーディング進捗取得 |
| 自動シーディング状態取得 | sys.dm_hadr_automatic_seeding | SELECT | 自動シーディング状態取得 |
| バックアップ | msdb.dbo.backupset | INSERT | バックアップ履歴記録 |
| リストア | master.sys.databases | UPDATE | データベース復元 |

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

#### sys.dm_hadr_physical_seeding_stats

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | local_database_name | WHERE句で対象DB指定 | シーディング進捗監視 |
| SELECT | transferred_size_bytes | - | 転送済みバイト数 |
| SELECT | database_size_bytes | - | DB総サイズ |
| SELECT | failure_message | - | エラー検出用 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ConnectionError | SQL Server接続失敗 | 接続情報確認、ネットワーク確認 |
| - | TimeoutError | 状態変更タイムアウト | タイムアウト設定値の調整 |
| - | SeedingFailure | 自動シーディング失敗 | エラーメッセージ確認、手動シーディングへ切替 |
| - | BackupError | バックアップ取得失敗 | 共有パス権限確認、ディスク容量確認 |
| - | RestoreError | リストア失敗 | ファイルパス確認、権限確認 |

### リトライ仕様

- 状態変更待機ループで`waitWhile`ミリ秒間隔でポーリング（デフォルト100ms）
- `timeoutExisting`秒でExisting状態待機タイムアウト（デフォルト60秒）
- `timeoutSynchronization`秒で同期完了タイムアウト（デフォルト86400秒=1日）

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

- 各ステップは独立して実行される
- SMOのCreate()、JoinAvailablityGroup()は内部でトランザクション管理
- 途中失敗時は部分的に処理が完了している可能性がある
- エラー時はStop-Functionでスキップし、次のデータベースを処理

## パフォーマンス要件

- タイムアウト設定は構成可能（DbatoolsConfig経由）
- 大規模データベースではAutomaticシーディングに時間を要する
- 進捗バーで同期状態をリアルタイム表示
- NoWaitオプションで即座に制御を返却可能

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

- SQL Server認証またはWindows認証対応
- MFA対応はConnect-DbaInstance経由で実現
- セカンダリ用に別途認証情報指定可能
- 共有パスアクセスにはサービスアカウント権限が必要
- Automaticシーディング時はCreateAnyDatabase権限が自動付与される

## 備考

- SMOのJoinAvailablityGroupメソッドには「Availablity」のタイプミスがあるが、SMOの仕様
- 設定値はSet-DbatoolsConfigで変更可能：
  - `commands.add-dbaagdatabase.timeout.existing`
  - `commands.add-dbaagdatabase.timeout.synchronization`
  - `commands.add-dbaagdatabase.wait.while`
  - `commands.add-dbaagdatabase.report.seeding`

---

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

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

### 推奨読解順序

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

まず、関連するSMOオブジェクトとパラメータセットを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Add-DbaAgDatabase.ps1 | `public/Add-DbaAgDatabase.ps1` | param()ブロックでParameterSetの構造を把握（206-246行目） |

**読解のコツ**: PowerShellのParameterSetNameは排他的なパラメータグループを定義する。NonPipelineとPipelineの2つのセットが存在する。

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

処理の起点となるbeginブロックとprocessブロックの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Add-DbaAgDatabase.ps1 | `public/Add-DbaAgDatabase.ps1` | beginブロックでタイムアウト設定値を取得（248-268行目） |
| 2-2 | Add-DbaAgDatabase.ps1 | `public/Add-DbaAgDatabase.ps1` | processブロック冒頭で進捗バー初期化（271-276行目） |

**主要処理フロー**:
1. **259-260行目**: タイムアウト値をDbatoolsConfigから取得
2. **264行目**: ポーリング間隔を取得
3. **268行目**: シーディング進捗レポート設定を取得

#### Step 3: 前提条件テストを理解する

Test-DbaAvailabilityGroupを呼び出して前提条件を検証する処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Add-DbaAgDatabase.ps1 | `public/Add-DbaAgDatabase.ps1` | Database配列のループでTest-DbaAvailabilityGroup呼び出し（279-299行目） |
| 3-2 | Add-DbaAgDatabase.ps1 | `public/Add-DbaAgDatabase.ps1` | InputObjectパイプラインでのテスト（301-320行目） |

**主要処理フロー**:
- **283-295行目**: Test-DbaAvailabilityGroup用のスプラットを構築
- **295行目**: テスト実行し結果を$testResultに蓄積

#### Step 4: 5ステップの処理を理解する

メイン処理である5つのステップを順に把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Add-DbaAgDatabase.ps1 | `public/Add-DbaAgDatabase.ps1` | Step 1: シーディングモード設定（337-366行目） |
| 4-2 | Add-DbaAgDatabase.ps1 | `public/Add-DbaAgDatabase.ps1` | Step 2: バックアップとリストア（368-442行目） |
| 4-3 | Add-DbaAgDatabase.ps1 | `public/Add-DbaAgDatabase.ps1` | Step 3: プライマリへのDB追加（444-488行目） |
| 4-4 | Add-DbaAgDatabase.ps1 | `public/Add-DbaAgDatabase.ps1` | Step 4: セカンダリへのDB追加（490-565行目） |
| 4-5 | Add-DbaAgDatabase.ps1 | `public/Add-DbaAgDatabase.ps1` | Step 5: 同期完了待機（567-654行目） |

**主要処理フロー**:
- **350-355行目**: SeedingMode変更とCreateAnyDatabase権限付与
- **377-383行目**: フル＋ログバックアップ取得
- **432行目**: セカンダリへのリストア実行
- **457行目**: AvailabilityDatabaseオブジェクト生成
- **462行目**: Create()メソッドでプライマリに追加
- **554行目**: JoinAvailablityGroup()でセカンダリに参加
- **608-617行目**: 自動シーディング進捗取得と進捗バー更新

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

```
Add-DbaAgDatabase
    │
    ├─ Test-DbaAvailabilityGroup (前提条件検証)
    │
    ├─ Grant-DbaAgPermission (Automatic時)
    │      └─ CreateAnyDatabase権限付与
    │
    ├─ Backup-DbaDatabase (Manualシーディング時)
    │      └─ Full + Log バックアップ
    │
    ├─ Restore-DbaDatabase (Manualシーディング時)
    │      └─ NoRecoveryでリストア
    │
    ├─ SMO AvailabilityDatabase.Create() (プライマリ)
    │
    ├─ Get-DbaAgDatabase (状態取得)
    │
    └─ SMO AvailabilityDatabase.JoinAvailablityGroup() (セカンダリ)
```

### データフロー図

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

Database名/Object ───────▶ Test-DbaAvailabilityGroup ───────▶ 検証結果
                                    │
                                    ▼
                          ┌─────────────────────┐
                          │ SeedingMode設定     │
                          └─────────────────────┘
                                    │
                    ┌───────────────┴───────────────┐
                    ▼                               ▼
             [Automatic]                      [Manual]
                    │                               │
                    │                    ┌──────────┴──────────┐
                    │                    ▼                     ▼
                    │            Backup-DbaDatabase    Use LastBackup
                    │                    │                     │
                    │                    └──────────┬──────────┘
                    │                               ▼
                    │                    Restore-DbaDatabase
                    │                               │
                    └───────────────┬───────────────┘
                                    ▼
                          ┌─────────────────────┐
                          │ プライマリにDB追加   │
                          │ (SMO Create)        │
                          └─────────────────────┘
                                    │
                                    ▼
                          ┌─────────────────────┐
                          │ セカンダリにDB追加   │
                          │ (SMO Join)          │
                          └─────────────────────┘
                                    │
                                    ▼
                          ┌─────────────────────┐
                          │ 同期完了待機        │───────────▶ AvailabilityDatabase
                          │ (進捗監視)          │              オブジェクト
                          └─────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Add-DbaAgDatabase.ps1 | `public/Add-DbaAgDatabase.ps1` | ソース | メインコマンド実装 |
| Test-DbaAvailabilityGroup.ps1 | `public/Test-DbaAvailabilityGroup.ps1` | ソース | 前提条件検証 |
| Grant-DbaAgPermission.ps1 | `public/Grant-DbaAgPermission.ps1` | ソース | AG権限付与 |
| Backup-DbaDatabase.ps1 | `public/Backup-DbaDatabase.ps1` | ソース | バックアップ取得 |
| Restore-DbaDatabase.ps1 | `public/Restore-DbaDatabase.ps1` | ソース | リストア実行 |
| Get-DbaAgDatabase.ps1 | `public/Get-DbaAgDatabase.ps1` | ソース | AG DB情報取得 |
