# 機能設計書 653-Test-DbaDiskAlignment

## 概要

本ドキュメントは、dbatools PowerShellモジュールの `Test-DbaDiskAlignment` 関数の機能設計を記述するものである。本機能はディスクパーティションのアライメントをテストし、SQL ServerのI/Oパフォーマンスに影響を与える可能性のあるアライメント問題を特定するコマンドレットである。

### 本機能の処理概要

**業務上の目的・背景**：
ディスクパーティションのアライメント不良は、SQL ServerのI/Oパフォーマンスに重大な悪影響を与える可能性がある。特にトランザクション量の多いシステムでは、パーティションの開始オフセットがストライプユニットサイズと適切に整合していない場合、読み取り/書き込み操作の効率が低下する。本機能は一般的なストライプユニットサイズ（64KB、128KB、256KB、512KB、1024KB）に対してパーティションオフセットをテストし、ベストプラクティスに準拠しているかを評価する。

**機能の利用シーン**：
- SQL Server環境構築前のストレージ検証時
- パフォーマンス問題のトラブルシューティング時
- ストレージ構成監査時
- サーバー移行前のストレージ検証時

**主要な処理内容**：
1. CIMセッションを使用したリモートサーバーへの接続
2. Win32_DiskPartitionからパーティション情報の取得
3. SQL Serverインスタンスの検出とデータベースファイルの配置ディスク特定（オプション）
4. 各パーティションの開始オフセットを複数のストライプユニットサイズでテスト
5. アライメント結果とベストプラクティス準拠状況の出力

**関連システム・外部連携**：
- CIM (Common Information Model) / WMI によるリモートサーバー情報取得
- Win32_DiskPartition クラスからのパーティション情報
- Win32_LogicalDiskToPartition アソシエーションによるドライブレター取得
- SQL Server接続によるデータベースファイル配置確認

**権限による制御**：
- CIM/WMIへのアクセス権限が必要
- NoSqlCheckを使用しない場合、SQL Serverへの接続権限も必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLI (PowerShell) | 主画面 | コマンドライン実行によるディスク検証 |

## 機能種別

データ取得処理（SELECT） / 診断処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ComputerName | DbaInstanceParameter[] | Yes | 対象サーバー名 | 必須、パイプライン入力可 |
| Credential | PSCredential | No | Windows接続用資格情報 | - |
| SqlCredential | PSCredential | No | SQL Server接続用資格情報 | - |
| NoSqlCheck | switch | No | SQL Serverファイル配置チェックをスキップ | - |
| EnableException | switch | No | 例外処理の有効化 | - |

### 入力データソース

- PowerShellコマンドラインからのパラメータ入力
- CIM/WMI経由でのOSパーティション情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | コンピュータ名 |
| Name | string | パーティション名またはドライブレター |
| PartitionSize | DbaSize | パーティションサイズ（バイト） |
| PartitionType | string | パーティションタイプ（Basic、Logical Disk Managerなど） |
| TestingStripeSize | DbaSize | テスト対象のストライプユニットサイズ |
| OffsetModuluCalculation | DbaSize | オフセット % ストライプサイズの計算結果 |
| StartingOffset | DbaSize | パーティション開始オフセット |
| IsOffsetBestPractice | bool | オフセットがベストプラクティス値か |
| IsBestPractice | bool | テスト対象ストライプサイズで整合しているか |
| NumberOfBlocks | long | パーティション内のブロック数 |
| BootPartition | bool | ブートパーティションか |
| PartitionBlockSize | int | パーティションのブロックサイズ |
| IsDynamicDisk | bool | ダイナミックディスクか |

### 出力先

PowerShellパイプライン（1パーティションにつき5オブジェクト - 各ストライプサイズごと）

## 処理フロー

### 処理シーケンス

```
1. 初期化処理（beginブロック）
   └─ CIMセッションオプションの設定（DCOM）
   └─ Get-DiskAlignment内部関数の定義

2. メイン処理（processブロック）
   └─ 各コンピュータに対して処理
       └─ ホスト名解決（Resolve-DbaNetworkName）
       └─ CIMセッション作成（WSMan優先、フォールバックでDCOM）
       └─ Get-DiskAlignment関数呼び出し

3. Get-DiskAlignment処理
   └─ Win32_DiskPartitionからパーティション情報取得
   └─ Win32_LogicalDiskToPartitionでドライブレター関連付け
   └─ SQL Serverインスタンス検出（NoSqlCheck無効時）
   └─ 各パーティションのSQL Serverファイル存在確認
   └─ ストライプサイズごとのアライメントテスト（64KB〜1024KB）
   └─ 結果オブジェクト生成と出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[各コンピュータをループ]
    B --> C[ホスト名解決]
    C --> D{解決成功?}
    D -->|No| E[スキップして次へ]
    D -->|Yes| F[CIMセッション作成WSMan]
    F --> G{接続成功?}
    G -->|No| H[CIMセッション作成DCOM]
    G -->|Yes| I[Get-DiskAlignment呼び出し]
    H --> J{接続成功?}
    J -->|No| K[エラー: CIM接続不可]
    J -->|Yes| I
    I --> L[パーティション情報取得]
    L --> M{NoSqlCheck?}
    M -->|Yes| N[全パーティション処理]
    M -->|No| O[SQL Server検出]
    O --> P[SQLファイル配置ディスク特定]
    P --> Q[該当パーティションのみ処理]
    N --> R[各パーティションをループ]
    Q --> R
    R --> S[各ストライプサイズでテスト]
    S --> T[結果オブジェクト出力]
    T --> U{次のストライプサイズ?}
    U -->|Yes| S
    U -->|No| V{次のパーティション?}
    V -->|Yes| R
    V -->|No| W{次のコンピュータ?}
    W -->|Yes| B
    W -->|No| X[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | ベストプラクティスオフセット | 64KB、128KB、256KB、512KB、1024KBのいずれかがベストプラクティス | オフセット評価時 |
| BR-002 | アライメント判定 | オフセット % ストライプサイズ == 0 で整合と判定 | 各ストライプサイズテスト時 |
| BR-003 | ダイナミックディスク警告 | Logical Disk Manager タイプの場合は結果が信頼できない旨を警告 | パーティションタイプ判定時 |
| BR-004 | テスト対象ストライプサイズ | 64KB、128KB、256KB、512KB、1024KBの5種類をテスト | 常時 |

### 計算ロジック

- オフセット（KB単位）: `$partition.StartingOffset / 1kb`
- アライメント判定: `$offset % $stripeSize == 0` で true なら整合
- ベストプラクティス判定: オフセットが 64, 128, 256, 512, 1024 のいずれかに等しいか

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| SQLファイル配置確認 | sys.master_files | SELECT | SQL Serverファイルの物理パス確認 |

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

#### sys.master_files

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | physical_name | `LIKE '$diskname%'` で対象ディスク上のファイルをカウント | NoSqlCheck無効時のみ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ホスト名解決エラー | コンピュータ名を解決できない | Stop-Function with -Continue、スキップして次へ |
| - | CIM接続エラー | WSManおよびDCOM両方で接続失敗 | Stop-Function with -Continue、スキップして次へ |
| - | 名前空間エラー | Win32_DiskPartitionが利用不可 | Stop-Function、非対応OS |
| - | SQL接続エラー | SQL Serverへの接続失敗 | Stop-Function with -Continue |

### リトライ仕様

- CIMセッション作成時、WSMan失敗でDCOMにフォールバック
- 自動リトライは実装されていない

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

読み取り専用処理のため、トランザクション管理は不要。

## パフォーマンス要件

- CIM経由のパーティション情報取得は通常数秒で完了
- 多数のSQL Serverインスタンスがある場合、ファイル配置確認に時間がかかる可能性がある
- 1パーティションにつき5つの結果オブジェクトが生成される

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

- CIM/WMIアクセスには管理者権限が推奨される
- Credentialパラメータによるセキュアな資格情報の受け渡し
- リモートサーバーのディスク情報を参照するため、適切なアクセス制御が必要

## 備考

- Windowsの標準機能ではストライプユニットサイズを確実に判定できないため、一般的な値でテストを行う
- ダイナミックディスクやサードパーティソフトウェアでプロビジョニングされたディスクは、結果が不正確な場合がある
- Windows Server 2008以降で新規インストールした場合、通常はアライメント問題は発生しない

---

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

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

### 推奨読解順序

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

出力オブジェクトの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Test-DbaDiskAlignment.ps1 | `public/Test-DbaDiskAlignment.ps1` | 270-285行目: 出力PSCustomObject定義 |

**読解のコツ**: DbaSize型は自動的にバイト単位を適切な単位に変換する dbatools のカスタム型である。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Test-DbaDiskAlignment.ps1 | `public/Test-DbaDiskAlignment.ps1` | 107-114行目: パラメータ定義 |
| 2-2 | Test-DbaDiskAlignment.ps1 | `public/Test-DbaDiskAlignment.ps1` | 290-338行目: processブロックのメインループ |

**主要処理フロー**:
1. **294-299行目**: コンピュータ名の解決
2. **305-327行目**: CIMセッション作成（WSMan優先、DCOMフォールバック）
3. **332-336行目**: Get-DiskAlignment呼び出し

#### Step 3: 内部関数Get-DiskAlignmentを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Test-DbaDiskAlignment.ps1 | `public/Test-DbaDiskAlignment.ps1` | 118-288行目: Get-DiskAlignment関数全体 |
| 3-2 | Test-DbaDiskAlignment.ps1 | `public/Test-DbaDiskAlignment.ps1` | 133-173行目: パーティション情報取得 |
| 3-3 | Test-DbaDiskAlignment.ps1 | `public/Test-DbaDiskAlignment.ps1` | 176-194行目: SQL Serverインスタンス検出 |
| 3-4 | Test-DbaDiskAlignment.ps1 | `public/Test-DbaDiskAlignment.ps1` | 197-230行目: SQL Serverファイル配置ディスク特定 |
| 3-5 | Test-DbaDiskAlignment.ps1 | `public/Test-DbaDiskAlignment.ps1` | 234-287行目: アライメントテストと結果生成 |

**主要処理フロー**:
- **137行目**: Win32_DiskPartitionからパーティション情報取得
- **151-166行目**: Win32_LogicalDiskToPartitionでドライブレター関連付け
- **178-191行目**: Win32_Serviceから SQL Server サービス検出
- **240行目**: テスト対象ストライプサイズ配列定義 `$stripe_units = @(64, 128, 256, 512, 1024)`
- **260-268行目**: アライメント判定とIsBestPractice設定

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

```
Test-DbaDiskAlignment
    │
    ├─ begin ブロック
    │      ├─ New-CimSessionOption（DCOMオプション設定）
    │      └─ Get-DiskAlignment（関数定義）
    │
    └─ process ブロック
           ├─ Resolve-DbaNetworkName
           │      └─ ホスト名解決
           │
           ├─ New-CimSession（WSMan or DCOM）
           │
           └─ Get-DiskAlignment
                  │
                  ├─ Get-CimInstance Win32_DiskPartition
                  │      └─ パーティション情報取得
                  │
                  ├─ Get-CimInstance Win32_LogicalDiskToPartition
                  │      └─ ドライブレター関連付け
                  │
                  ├─ Get-CimInstance Win32_Service
                  │      └─ SQL Server サービス検出
                  │
                  ├─ Connect-DbaInstance（NoSqlCheck無効時）
                  │      └─ SQL Server接続
                  │
                  ├─ Server.Query（sys.master_files参照）
                  │      └─ ファイル配置確認
                  │
                  └─ アライメントテスト
                         └─ 各ストライプサイズで判定
```

### データフロー図

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

ComputerName ───┐
                ├──▶ Resolve-DbaNetworkName
Credential ─────┤            │
                │            ▼
                │    New-CimSession
                │            │
                │            ▼
                │    Win32_DiskPartition ──▶ パーティション情報
                │            │
                │            ▼
                │    Win32_LogicalDiskToPartition ──▶ ドライブレター
                │            │
NoSqlCheck ─────┤            ▼
                │    ┌───────┴───────┐
                │    │ NoSqlCheck?  │
                │    └───────┬───────┘
SqlCredential ──┤    No│         │Yes
                │       ▼         │
                │    SQL Server   │
                │    ファイル確認 │
                │       │         │
                │       ▼         ▼
                │    対象パーティション特定
                │            │
                │            ▼
                │    ストライプサイズテスト
                │    (64KB, 128KB, 256KB, 512KB, 1024KB)
                │            │
                │            ▼
                └────────────────────────────────▶ PSCustomObject[]
                                                  (パーティション×5)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Test-DbaDiskAlignment.ps1 | `public/Test-DbaDiskAlignment.ps1` | ソース | メイン機能実装 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続処理 |
| Resolve-DbaNetworkName.ps1 | `public/Resolve-DbaNetworkName.ps1` | ソース | ホスト名解決処理 |
