# 機能設計書 278-Set-DbaDbMirror

## 概要

本ドキュメントは、データベースミラーリングのパートナー、ウィットネス、安全性レベル、および運用状態を構成するdbatools PowerShellコマンド`Set-DbaDbMirror`の機能設計書です。

### 本機能の処理概要

`Set-DbaDbMirror`は、パートナーサーバー、ウィットネスサーバー、安全性レベルの設定、またはミラーの状態変更により、データベースミラーリング構成を変更します。この関数により、手動でALTER DATABASE文を作成することなく、既存のミラーリングされたデータベースを再構成できます。自動フェイルオーバー用のウィットネスサーバーの追加や変更、同期モードと非同期モード間の安全性レベルの調整、中断、再開、フェイルオーバー操作などのミラー状態の制御に使用します。

**業務上の目的・背景**：ミラーリング構成の変更は運用中に頻繁に発生します。安全性レベルの変更、ウィットネスの追加/変更、フェイルオーバー操作などを、一貫したインターフェースで実行できることで、DBAの作業効率と正確性が向上します。

**機能の利用シーン**：
- ミラーリングパートナーの変更
- ウィットネスサーバーの追加/変更/削除
- 同期/非同期モードの切り替え
- ミラーリングの中断/再開
- 手動フェイルオーバーの実行

**主要な処理内容**：
1. パートナーサーバーの設定（ALTER DATABASE SET PARTNER）
2. ウィットネスサーバーの設定（ALTER DATABASE SET WITNESS）
3. 安全性レベルの変更（ALTER DATABASE SET PARTNER SAFETY）
4. ミラーリング状態の変更（ChangeMirroringState）

**関連システム・外部連携**：SMO (SQL Server Management Objects) を使用し、ALTER DATABASE文を内部で実行します。

**権限による制御**：データベースのALTER権限が必要です。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | PowerShellコンソール | 主画面 | コマンド実行・結果表示 |

## 機能種別

構成変更操作（ALTER DATABASE）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 対象SQL Serverインスタンス | - |
| SqlCredential | PSCredential | No | 代替認証情報 | Windows/SQL認証対応 |
| Database | string[] | No | 対象データベース名 | SqlInstance指定時は必須 |
| Partner | string | No | ミラーリングパートナーエンドポイント | TCP://server:port形式 |
| Witness | string | No | ウィットネスエンドポイント | TCP://server:port形式 |
| SafetyLevel | string | No | トランザクション安全性モード | ValidateSet: Full/Off/None |
| State | string | No | ミラーリング状態 | ValidateSet: ForceFailoverAndAllowDataLoss/Failover/RemoveWitness/Resume/Suspend/Off |
| InputObject | Microsoft.SqlServer.Management.Smo.Database[] | No | パイプライン入力データベース | ValueFromPipeline |
| EnableException | switch | No | 例外処理の有効化 | - |
| WhatIf | switch | No | 実行シミュレーション | SupportsShouldProcess |
| Confirm | switch | No | 確認プロンプト | ConfirmImpact='High' |

### State オプションの詳細

| State値 | 説明 | 対応SQL |
|---------|------|---------|
| ForceFailoverAndAllowDataLoss | データ損失を許容した強制フェイルオーバー | SET PARTNER FORCE_SERVICE_ALLOW_DATA_LOSS |
| Failover | 安全なフェイルオーバー | SET PARTNER FAILOVER |
| RemoveWitness | ウィットネスの削除 | SET WITNESS OFF |
| Resume | 中断されたミラーリングの再開 | SET PARTNER RESUME |
| Suspend | ミラーリングの中断 | SET PARTNER SUSPEND |
| Off | ミラーリングの停止 | SET PARTNER OFF |

### 入力データソース

- SQL Serverインスタンスへの接続情報
- Get-DbaDatabaseからのデータベースオブジェクト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| （SMO Databaseプロパティ） | - | 変更されたデータベースオブジェクト（State指定時のみ） |

### 出力先

- State指定時: パイプライン出力（Microsoft.SqlServer.Management.Smo.Database オブジェクト）
- Partner/Witness/SafetyLevel指定時: 出力なし

## 処理フロー

### 処理シーケンス

```
1. パラメータ検証
   └─ SqlInstance指定時はDatabaseが必須
2. データベースオブジェクト取得
   └─ Get-DbaDatabaseを使用
3. 各データベースに対してループ処理
   └─ 設定変更の実行
4. Partner設定（指定時）
   └─ ALTER DATABASE SET PARTNER
5. Witness設定（指定時）
   └─ ALTER DATABASE SET WITNESS
6. SafetyLevel設定（指定時）
   └─ ALTER DATABASE SET PARTNER SAFETY
7. State変更（指定時）
   └─ ChangeMirroringState + Alter
   └─ データベースオブジェクト出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{SqlInstance指定<br/>かつ<br/>Database未指定?}
    B -->|Yes| C[エラー終了]
    B -->|No| D[SqlInstanceループ]
    D --> E[Get-DbaDatabase実行]
    E --> F[データベースループ]
    F --> G{Partner指定?}
    G -->|Yes| H[ALTER DATABASE<br/>SET PARTNER]
    G -->|No| I{Witness指定?}
    H --> I
    I -->|Yes| J[ALTER DATABASE<br/>SET WITNESS]
    I -->|No| K{SafetyLevel指定?}
    J --> K
    K -->|Yes| L[ALTER DATABASE<br/>SET PARTNER SAFETY]
    K -->|No| M{State指定?}
    L --> M
    M -->|Yes| N[ChangeMirroringState]
    M -->|No| O[次のDB]
    N --> P[db.Alter]
    P --> Q[データベースオブジェクト出力]
    Q --> O
    O --> R{次のDB<br/>あり?}
    R -->|Yes| F
    R -->|No| S{次のインスタンス<br/>あり?}
    S -->|Yes| D
    S -->|No| T[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-278-01 | Database必須 | SqlInstance指定時はDatabaseパラメータ必須 | SqlInstance使用時 |
| BR-278-02 | T-SQL優先 | Partner/Witness設定はT-SQLを使用（SMOのAlterが常に動作しないため） | Partner/Witness指定時 |
| BR-278-03 | SMO使用 | State変更はChangeMirroringState + Alterを使用 | State指定時 |
| BR-278-04 | 出力制御 | State指定時のみデータベースオブジェクトを出力 | State指定時 |
| BR-278-05 | 高確認レベル | ConfirmImpact='High'で確認プロンプト表示 | デフォルト |

### 計算ロジック

各設定のSQL生成:
```powershell
# Partner設定
"ALTER DATABASE $db SET PARTNER = N'$Partner'"

# Witness設定
"ALTER DATABASE $db SET WITNESS = N'$Witness'"

# SafetyLevel設定
"ALTER DATABASE $db SET PARTNER SAFETY $SafetyLevel"

# State変更（SMO経由）
$db.ChangeMirroringState($State)
$db.Alter()
```

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

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

| 操作 | 対象 | 操作種別 | 概要 |
|-----|-------------|---------|------|
| パートナー設定 | Database | ALTER DATABASE | SET PARTNER = 'endpoint' |
| ウィットネス設定 | Database | ALTER DATABASE | SET WITNESS = 'endpoint' |
| 安全性レベル変更 | Database | ALTER DATABASE | SET PARTNER SAFETY Full/Off |
| 状態変更 | Database | SMO Alter | ChangeMirroringState |

### SQL文（内部で実行）

#### パートナー設定
```sql
ALTER DATABASE [dbname] SET PARTNER = N'TCP://server:port'
```

#### ウィットネス設定
```sql
ALTER DATABASE [dbname] SET WITNESS = N'TCP://server:port'
```

#### 安全性レベル変更
```sql
ALTER DATABASE [dbname] SET PARTNER SAFETY FULL
-- or
ALTER DATABASE [dbname] SET PARTNER SAFETY OFF
```

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | パラメータエラー | SqlInstance指定でDatabase未指定 | Stop-Function実行 |
| - | 設定エラー | ALTER DATABASE失敗 | Stop-Function実行 |
| - | SMOエラー | ChangeMirroringState失敗 | try-catchでキャッチ |

### リトライ仕様

リトライ処理なし。エラー発生時はStop-Functionで処理停止。

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

- 各ALTER DATABASE文はSQL Serverによって個別にトランザクション管理

## パフォーマンス要件

- 単一のALTER DATABASE文のため即座に完了

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

- ConfirmImpact='High'による確認プロンプト
- -WhatIfによる事前シミュレーション
- PSCredentialによる安全な認証情報管理

## 備考

- PartnerとWitnessの設定はT-SQLを使用（SMOのAlterがrestoring DBに対して常に動作しないため）
- コードにコメント: `# use t-sql cuz $db.Alter() does not always work against restoring dbs`

---

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

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

### 推奨読解順序

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

State列挙値と出力パターンを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Set-DbaDbMirror.ps1 | `public/Set-DbaDbMirror.ps1` | 111-114行目: SafetyLevelとStateのValidateSet |

**読解のコツ**: Partner/Witnessと SafetyLevel/State で処理パターンが異なります。前者はT-SQL直接実行、後者はSMOまたはT-SQLを使用します。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Set-DbaDbMirror.ps1 | `public/Set-DbaDbMirror.ps1` | 関数全体の構造（160行） |

**主要処理フロー**:
1. **104行目**: CmdletBinding - SupportsShouldProcess, ConfirmImpact='High'
2. **105-118行目**: パラメータ定義（11個）
3. **119-123行目**: パラメータ検証
4. **124-126行目**: SqlInstanceループとGet-DbaDatabase
5. **128-158行目**: 設定変更処理ループ
6. **130-134行目**: Partner設定（T-SQL）
7. **135-138行目**: Witness設定（T-SQL）
8. **140-146行目**: SafetyLevel設定（T-SQL）
9. **148-154行目**: State変更（SMO）

#### Step 3: T-SQL vs SMO の使い分けを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Set-DbaDbMirror.ps1 | `public/Set-DbaDbMirror.ps1` | 132行目: コメント説明 |

**T-SQL使用の理由**:
- `# use t-sql cuz $db.Alter() does not always work against restoring dbs`
- Partner/Witness設定時、対象がrestoringデータベースの場合にSMOが失敗する可能性がある

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

```
Set-DbaDbMirror
    │
    ├─ Test-Bound (パラメータ検証)
    │      └─ SqlInstance指定時はDatabase必須
    │
    ├─ foreach ($instance in $SqlInstance)
    │      └─ Get-DbaDatabase
    │             └─ Connect-DbaInstance
    │
    └─ foreach ($db in $InputObject)
           │
           ├─ [Partner指定] ShouldProcess
           │      └─ $db.Parent.Query("ALTER DATABASE SET PARTNER")
           │
           ├─ [Witness指定] ShouldProcess
           │      └─ $db.Parent.Query("ALTER DATABASE SET WITNESS")
           │
           ├─ [SafetyLevel指定] ShouldProcess
           │      └─ $db.Parent.Query("ALTER DATABASE SET PARTNER SAFETY")
           │
           └─ [State指定] ShouldProcess
                  ├─ $db.ChangeMirroringState($State)
                  ├─ $db.Alter()
                  └─ $db 出力
```

### データフロー図

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

SqlInstance ───────▶ Get-DbaDatabase ──────▶ Database Objects
      +                     │
Database ──────────────────┤
      or                    │
InputObject ────────────────┤
                            ▼
Partner ───────────▶ ALTER DATABASE SET PARTNER ──▶ (出力なし)
                            │
Witness ───────────▶ ALTER DATABASE SET WITNESS ──▶ (出力なし)
                            │
SafetyLevel ───────▶ ALTER DATABASE SET PARTNER SAFETY ▶ (出力なし)
                            │
State ─────────────▶ ChangeMirroringState + Alter
                            │
                            ▼
                    Database Object ──────────▶ 出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Set-DbaDbMirror.ps1 | `public/Set-DbaDbMirror.ps1` | ソース | メイン機能実装（160行） |
| Set-DbaDbMirror.Tests.ps1 | `tests/Set-DbaDbMirror.Tests.ps1` | テスト | 単体テスト |
| Get-DbaDatabase.ps1 | `public/Get-DbaDatabase.ps1` | ソース | 依存関数 |
