# 機能設計書 473-Set-DbaRgWorkloadGroup

## 概要

本ドキュメントは、SQL Server Resource Governorのワークロードグループ設定を変更するPowerShellコマンド「Set-DbaRgWorkloadGroup」の機能設計書である。

### 本機能の処理概要

Set-DbaRgWorkloadGroupは、Resource Governorのワークロードグループに対して、クエリのリソース消費と制限を制御する設定を変更する機能である。CPU、メモリ、並列度の設定を調整し、特定のワークロードカテゴリに対するリソース割り当てポリシーを管理する。

**業務上の目的・背景**：企業のSQL Server環境では、異なる種類のワークロード（OLTPトランザクション、レポートクエリ、ETLジョブなど）が同一インスタンス上で実行される。ワークロードグループを使用することで、各ワークロードカテゴリに対してリソース消費の優先度や制限を設定し、サービスレベルアグリーメント（SLA）を実現できる。特に、リソース集約的なクエリが重要なアプリケーションに影響を与えることを防止するために不可欠である。

**機能の利用シーン**：
- 重要なアプリケーション用ワークロードグループの優先度を「HIGH」に変更する場合
- レポート処理用グループの最大CPU時間を制限する場合
- 開発者用グループのMAXDOP（最大並列度）を制限する場合
- 複数のワークロードグループに対して一括で同一設定を適用する場合

**主要な処理内容**：
1. SQL Serverインスタンスへの接続またはパイプライン入力の処理
2. 指定されたリソースプール内のワークロードグループ取得
3. 重要度（Importance）、メモリ、CPU、並列度などの設定変更
4. Alter()メソッドによるグループ設定の適用
5. Resource Governorの再構成（SkipReconfigureでスキップ可能）
6. 更新後のワークロードグループ情報の出力

**関連システム・外部連携**：リソースプールとの階層関係。ワークロードグループは必ず特定のリソースプールに所属し、そのプールのリソース制限内で動作する。

**権限による制御**：ALTER RESOURCE GOVERNOR権限またはCONTROL SERVER権限が必要。sysadmin固定サーバーロールのメンバーも操作可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | SQL Server Management Studio - Resource Governor | 参照画面 | ワークロードグループ設定の確認 |

## 機能種別

設定変更処理 / SMOオブジェクト操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 対象SQL Serverインスタンス | - |
| SqlCredential | PSCredential | No | SQL Server接続用の資格情報 | - |
| WorkloadGroup | string[] | No | 変更対象のワークロードグループ名 | InputObjectと排他 |
| ResourcePool | string | No | ワークロードグループが所属するリソースプール名 | WorkloadGroup指定時に必要 |
| ResourcePoolType | string | No | プールタイプ（Internal/External） | ValidateSet: Internal, External |
| Importance | string | No | リソース優先度 | ValidateSet: LOW, MEDIUM, HIGH |
| RequestMaximumMemoryGrantPercentage | int | No | 単一クエリの最大メモリ許可率 | ValidateRange(1, 100) |
| RequestMaximumCpuTimeInSeconds | int | No | 単一リクエストの最大CPU時間（秒） | ValidateRange(0, int.MaxValue) |
| RequestMemoryGrantTimeoutInSeconds | int | No | メモリ許可タイムアウト（秒） | ValidateRange(0, int.MaxValue) |
| MaximumDegreeOfParallelism | int | No | 最大並列度（MAXDOP） | ValidateRange(0, 64) |
| GroupMaximumRequests | int | No | グループ内の同時リクエスト最大数 | ValidateRange(0, int.MaxValue) |
| SkipReconfigure | switch | No | 自動再構成をスキップ | - |
| InputObject | WorkloadGroup[] | No | Get-DbaRgWorkloadGroupからのパイプ入力 | - |
| WhatIf | switch | No | 実行内容のプレビュー | - |
| Confirm | switch | No | 実行前の確認プロンプト | - |
| EnableException | switch | No | 例外をスローするかどうか | - |

### 入力データソース

- パイプライン経由のWorkloadGroupオブジェクト（Get-DbaRgWorkloadGroupから）
- SqlInstance、ResourcePool、WorkloadGroupパラメータの組み合わせ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Name | string | ワークロードグループ名 |
| Importance | string | リソース優先度（LOW/MEDIUM/HIGH） |
| RequestMaximumMemoryGrantPercentage | int | 単一クエリの最大メモリ許可率 |
| RequestMaximumCpuTimeInSeconds | int | 単一リクエストの最大CPU時間 |
| RequestMemoryGrantTimeoutInSeconds | int | メモリ許可タイムアウト |
| MaximumDegreeOfParallelism | int | 最大並列度 |
| GroupMaximumRequests | int | 同時リクエスト最大数 |
| Parent | ResourcePool | 所属するリソースプール |

### 出力先

パイプライン出力（Microsoft.SqlServer.Management.Smo.WorkloadGroup オブジェクト）

## 処理フロー

### 処理シーケンス

```
1. 入力検証
   └─ InputObjectまたはWorkloadGroup、SqlInstanceの指定を確認
2. インスタンス接続とワークロードグループ取得
   └─ ResourcePoolTypeに基づいてプールを取得し、その中のワークロードグループを取得
3. ワークロードグループ設定の変更
   └─ 指定されたパラメータのみ対応するプロパティを更新
4. グループ変更の適用
   └─ $wklGroup.Alter()で変更を適用
5. Resource Governor再構成
   └─ SkipReconfigureでない場合は$server.ResourceGovernor.Alter()を実行
6. 結果出力
   └─ Get-DbaRgResourcePoolとGet-DbaRgWorkloadGroupで更新後のグループを取得して出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{InputObject指定?}
    B -->|No| C{WorkloadGroup/SqlInstance指定?}
    C -->|No| D[エラー: パラメータ不足]
    C -->|Yes| E[Connect-DbaInstanceで接続]
    B -->|Yes| F[InputObjectを使用]
    E --> G[ResourcePoolTypeに基づきプール取得]
    G --> H[WorkloadGroupをフィルタリング]
    F --> I[foreach wklGroup]
    H --> I
    I --> J[親プールとサーバーを取得]
    J --> K[プールタイプを判定]
    K --> L{Importance指定?}
    L -->|Yes| M[Importanceを設定]
    L -->|No| N{Memory設定指定?}
    M --> N
    N -->|Yes| O[Memory設定を適用]
    N -->|No| P{CPU設定指定?}
    O --> P
    P -->|Yes| Q[CPU設定を適用]
    P -->|No| R{MAXDOP指定?}
    Q --> R
    R -->|Yes| S[MAXDOPを設定]
    R -->|No| T{GroupMaxRequests指定?}
    S --> T
    T -->|Yes| U[GroupMaxRequestsを設定]
    T -->|No| V[Alter実行]
    U --> V
    V --> W{SkipReconfigure?}
    W -->|Yes| X[警告: 手動再構成必要]
    W -->|No| Y[ResourceGovernor.Alter実行]
    X --> Z[結果出力]
    Y --> Z
    Z --> AA[次のグループへ]
    AA --> I
    D --> AB[終了]
    AA --> AB
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 必須パラメータ | InputObjectまたはWorkloadGroup+SqlInstanceの組み合わせが必要 | 常時 |
| BR-002 | リソースプール指定 | WorkloadGroup指定時はResourcePoolも指定する必要がある | WorkloadGroupパラメータ使用時 |
| BR-003 | 重要度の値 | ImportanceはLOW、MEDIUM、HIGHの3値のみ | Importanceパラメータ指定時 |
| BR-004 | プランキャッシュ | プラン影響設定は新しいクエリプランに対してのみ有効 | MAXDOP等の設定変更時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| グループ設定変更 | sys.resource_governor_workload_groups | UPDATE | ALTER WORKLOAD GROUPにより更新 |
| 再構成 | sys.resource_governor_configuration | UPDATE | ALTER RESOURCE GOVERNORにより更新 |

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

#### sys.resource_governor_workload_groups

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | importance | LOW/MEDIUM/HIGH | SMO経由で更新 |
| UPDATE | request_max_memory_grant_percent | 1-100 | SMO経由で更新 |
| UPDATE | request_max_cpu_time_sec | 0-2147483647 | SMO経由で更新 |
| UPDATE | request_memory_grant_timeout_sec | 0-2147483647 | SMO経由で更新 |
| UPDATE | max_dop | 0-64 | SMO経由で更新 |
| UPDATE | group_max_requests | 0-2147483647 | SMO経由で更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ParameterError | パラメータエラー | WorkloadGroupもInputObjectも指定されていない | Stop-Functionでエラーメッセージを表示 |
| ConnectionError | 接続エラー | SQL Serverに接続できない | Stop-Functionで処理を中断し次のインスタンスへ |
| AlterError | 変更エラー | ワークロードグループの変更に失敗 | Stop-Functionで処理を中断 |
| ReconfigureError | 再構成エラー | Resource Governorの再構成に失敗 | Stop-Functionで処理を中断 |

### リトライ仕様

リトライ処理は実装されていない。エラー発生時は次のグループの処理に移行する。

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

SMOのAlter()メソッドによる暗黙的なトランザクション管理。グループ変更とResource Governor再構成は別々のAlter()呼び出しで実行される。

## パフォーマンス要件

特になし。通常は数秒以内に完了する軽量な操作。

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

- ALTER RESOURCE GOVERNOR権限またはCONTROL SERVER権限が必要
- SQL認証使用時は資格情報がSecureStringとして管理される
- WhatIfパラメータによる事前確認が可能

## 備考

- MAXDOPやメモリ設定の変更は、既存のクエリプランには影響しない
- プロシージャキャッシュのクリアが必要な場合がある
- SkipReconfigureを使用した場合、変更は次回の手動再構成またはサーバー再起動まで反映されない

---

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

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

### 推奨読解順序

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

SMOのWorkloadGroupオブジェクトの構造と、リソースプールとの階層関係を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Set-DbaRgWorkloadGroup.ps1 | `public/Set-DbaRgWorkloadGroup.ps1` | 161-166行目でワークロードグループと親プールの関係を確認 |

**読解のコツ**: WorkloadGroupは$resPool.WorkloadGroupsコレクションに含まれ、Parentプロパティで親プールにアクセスできる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Set-DbaRgWorkloadGroup.ps1 | `public/Set-DbaRgWorkloadGroup.ps1` | 111-135行目のパラメータ定義を確認 |

**主要処理フロー**:
1. **137-145行目**: 入力検証（InputObjectまたはWorkloadGroup/SqlInstanceの確認）
2. **147-159行目**: インスタンス接続とワークロードグループ取得
3. **161-185行目**: プロパティ設定（Importance、Memory、CPU、MAXDOP等）
4. **188-194行目**: Alter()でグループ変更を適用
5. **197-205行目**: SkipReconfigureの判定とResource Governor再構成
6. **206行目**: Get-DbaRgResourcePoolとGet-DbaRgWorkloadGroupで結果出力

#### Step 3: プールタイプ判定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Set-DbaRgWorkloadGroup.ps1 | `public/Set-DbaRgWorkloadGroup.ps1` | 163-166行目のタイプ判定ロジック |

**主要処理フロー**:
- **163行目**: $resPool = $wklGroup.Parentで親プールを取得
- **164-166行目**: GetType().Nameで"ResourcePool"か"ExternalResourcePool"を判定

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

```
Set-DbaRgWorkloadGroup
    │
    ├─ Connect-DbaInstance
    │      └─ SQL Server接続確立
    │
    ├─ $server.ResourceGovernor.ResourcePools（Internal）
    │      └─ リソースプールコレクションを取得
    │
    ├─ $server.ResourceGovernor.ExternalResourcePools（External）
    │      └─ 外部リソースプールコレクションを取得
    │
    ├─ $resPool.WorkloadGroups
    │      └─ ワークロードグループコレクションを取得
    │
    ├─ $wklGroup.Alter()
    │      └─ グループ設定の適用
    │
    ├─ $server.ResourceGovernor.Alter()
    │      └─ Resource Governor再構成
    │
    └─ Get-DbaRgResourcePool | Get-DbaRgWorkloadGroup
           └─ 更新後のワークロードグループを取得して出力
```

### データフロー図

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

SqlInstance             ───▶ Connect-DbaInstance ───▶ $server
ResourcePool            ───▶ プール取得 ───▶ $resPool
WorkloadGroup           ───▶ グループ取得 ───▶ $wklGroup
ResourcePoolType        ───▶ 取得対象の決定
                                       │
Importance              ───▶ プロパティ設定 ───▶ $wklGroup.Alter()
RequestMaxMemoryGrant                  │
RequestMaxCpuTime                      ▼
MemoryGrantTimeout      ───▶    ResourceGovernor.Alter()
MaximumDegreeOfParallelism             │
GroupMaximumRequests                   ▼
                               Get-DbaRgResourcePool
                                       │
                                       ▼
                               Get-DbaRgWorkloadGroup
                                       │
                                       ▼
                               [WorkloadGroupオブジェクト]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Set-DbaRgWorkloadGroup.ps1 | `public/Set-DbaRgWorkloadGroup.ps1` | ソース | メイン処理ロジック |
| Get-DbaRgWorkloadGroup.ps1 | `public/Get-DbaRgWorkloadGroup.ps1` | ソース | ワークロードグループ取得用コマンド |
| Get-DbaRgResourcePool.ps1 | `public/Get-DbaRgResourcePool.ps1` | ソース | リソースプール取得用コマンド |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続用コマンド |
