# 機能設計書 126-Get-DbaIoLatency

## 概要

本ドキュメントは、SQL Serverの全データベースファイルに対するI/Oレイテンシメトリクスを取得し、ストレージパフォーマンスのボトルネックを特定するGet-DbaIoLatency機能の設計仕様を記載する。

### 本機能の処理概要

Get-DbaIoLatencyは、sys.dm_io_virtual_file_statsを使用して各データベースファイルの詳細なI/Oパフォーマンス統計を収集する機能である。読み取りレイテンシ、書き込みレイテンシ、全体レイテンシ、およびスループット統計を計算して返却する。

**業務上の目的・背景**：データベースパフォーマンス問題の原因の多くはストレージI/Oに起因する。DBAは、どのデータベースファイルが高いI/O待機時間を示しているかを特定し、ストレージシステムの改善やファイル配置の最適化を行う必要がある。本機能により、Paul Randal氏のパフォーマンスチューニング手法に基づいたI/O分析が可能。

**機能の利用シーン**：
- ストレージパフォーマンスボトルネックの診断
- データベースファイルごとのI/O待機時間分析
- パフォーマンスベースラインの取得
- ストレージ容量計画とリソース配分

**主要な処理内容**：
1. SQL Server 2005以降のインスタンスに接続（MinimumVersion 9）
2. sys.dm_io_virtual_file_statsとsys.master_filesを結合してクエリ
3. 読み取り/書き込みレイテンシとスループットを計算
4. 各ファイルの統計をPSCustomObjectとして出力

**関連システム・外部連携**：SQL Server動的管理ビュー（DMV）

**権限による制御**：VIEW SERVER STATE権限が必要。sysadminロールのメンバーは全ての情報を取得可能。

## 関連画面

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

## 機能種別

データ取得(SELECT) / パフォーマンス診断

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstance[] | Yes | 対象SQL Serverインスタンス | Mandatory, ValueFromPipeline |
| SqlCredential | PSCredential | No | 代替認証情報 | Windows/SQL認証対応 |
| EnableException | switch | No | 例外を直接スローするか | - |

### 入力データソース

- SQL Serverインスタンスへの接続パラメータ
- sys.dm_io_virtual_file_stats、sys.master_files

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 | デフォルト表示 |
|--------|-----|------|--------------|
| ComputerName | string | SQL Serverホストのコンピュータ名 | Yes |
| InstanceName | string | SQL Serverインスタンス名 | Yes |
| SqlInstance | string | 完全修飾インスタンス名 | Yes |
| DatabaseId | int | データベースの内部ID | Yes |
| DatabaseName | string | データベース名 | Yes |
| FileId | int | データベース内のファイルID | Yes |
| PhysicalName | string | ファイルの物理パス | Yes |
| NumberOfReads | bigint | インスタンス起動後の読み取り回数 | Yes |
| IoStallRead | bigint | 読み取り待機時間の合計（ミリ秒） | Yes |
| NumberOfwrites | bigint | インスタンス起動後の書き込み回数 | Yes |
| IoStallWrite | bigint | 書き込み待機時間の合計（ミリ秒） | Yes |
| IoStall | bigint | I/O待機時間の累計（読み取り+書き込み） | Yes |
| NumberOfBytesRead | bigint | 読み取ったバイト数の合計 | Yes |
| NumberOfBytesWritten | bigint | 書き込んだバイト数の合計 | Yes |
| SampleMilliseconds | bigint | インスタンス起動からの経過時間（ミリ秒） | Yes |
| SizeOnDiskBytes | bigint | ファイルの現在のディスクサイズ（バイト） | Yes |
| FileHandle | varbinary | 内部ファイルハンドル | No |
| ReadLatency | int | 平均読み取りレイテンシ（ミリ秒） | No |
| WriteLatency | int | 平均書き込みレイテンシ（ミリ秒） | No |
| Latency | int | 平均I/Oレイテンシ（ミリ秒） | No |
| AvgBPerRead | bigint | 読み取り操作あたりの平均バイト数 | No |
| AvgBPerWrite | bigint | 書き込み操作あたりの平均バイト数 | No |
| AvgBPerTransfer | bigint | I/O操作あたりの平均バイト数 | No |

### 出力先

- PowerShellパイプライン（PSCustomObject）
- コンソール出力（Select-DefaultViewで一部プロパティを除外）

## 処理フロー

### 処理シーケンス

```
1. BEGINブロックでSQLクエリ文字列を定義
   └─ レイテンシとスループットの計算ロジックを含む

2. 各SqlInstanceをループ処理
   └─ Connect-DbaInstance -MinimumVersion 9で接続

3. SQLクエリを実行
   └─ sys.dm_io_virtual_file_stats + sys.master_files

4. 各行をPSCustomObjectに変換
   └─ 全プロパティをマッピング

5. Select-DefaultViewで出力プロパティを制御
   └─ レイテンシ/スループット計算値はデフォルト非表示
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[SQLクエリ文字列定義]
    B --> C{SqlInstanceループ}
    C -->|各インスタンス| D[Connect-DbaInstance]
    D --> E{バージョン確認}
    E -->|SQL 2005未満| F[Stop-Function]
    E -->|SQL 2005以上| G[クエリ実行]
    F --> C
    G --> H{結果行ループ}
    H -->|各行| I[PSCustomObject作成]
    I --> J[Select-DefaultView出力]
    J --> H
    H -->|終了| C
    C -->|全インスタンス完了| K[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 最小バージョン | SQL Server 2005（バージョン9）以上が必要 | 接続時 |
| BR-002 | ゼロ除算防止 | 読み取り/書き込み回数が0の場合、レイテンシは0を返す | 計算時 |
| BR-003 | 累積値 | 値はインスタンス起動以降の累積値 | 全ての統計 |

### 計算ロジック

- **ReadLatency**: `CASE WHEN num_of_reads = 0 THEN 0 ELSE io_stall_read_ms / num_of_reads END`
- **WriteLatency**: `CASE WHEN num_of_writes = 0 THEN 0 ELSE io_stall_write_ms / num_of_writes END`
- **Latency**: `CASE WHEN (num_of_reads + num_of_writes) = 0 THEN 0 ELSE io_stall / (num_of_reads + num_of_writes) END`
- **AvgBPerRead**: `CASE WHEN num_of_reads = 0 THEN 0 ELSE num_of_bytes_read / num_of_reads END`
- **AvgBPerWrite**: `CASE WHEN num_of_writes = 0 THEN 0 ELSE num_of_bytes_written / num_of_writes END`
- **AvgBPerTransfer**: `CASE WHEN (num_of_reads + num_of_writes) = 0 THEN 0 ELSE (num_of_bytes_read + num_of_bytes_written) / (num_of_reads + num_of_writes) END`

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| I/O統計取得 | sys.dm_io_virtual_file_stats | SELECT | 仮想ファイルI/O統計取得 |
| ファイル情報取得 | sys.master_files | SELECT | データベースファイルメタデータ取得 |

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

#### sys.dm_io_virtual_file_stats

| 操作 | 項目（カラム名） | 取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | database_id, file_id, num_of_reads, io_stall_read_ms, num_of_writes, io_stall_write_ms, io_stall, num_of_bytes_read, num_of_bytes_written, sample_ms, size_on_disk_bytes, file_handle | NULL, NULL（全ファイル） | DMF呼び出し |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ConnectionError | 接続エラー | SQL Serverインスタンスへの接続失敗 | Stop-Function -Continueで次へ |
| - | バージョンエラー | SQL Server 2005未満 | MinimumVersion 9で自動拒否 |

### リトライ仕様

リトライ処理なし。接続失敗時は警告出力後に次のインスタンスを処理。

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

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

## パフォーマンス要件

- DMVへの軽量クエリのため、通常は高速に完了
- 大量のデータベースファイルがある場合でも数秒以内

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

- VIEW SERVER STATE権限が必要
- SqlCredentialによる認証情報の安全な受け渡し
- Windows認証、SQL認証、Active Directory認証に対応

## 備考

- 全てのプロパティを表示するには`Select-Object *`を使用
- レイテンシ値はミリ秒単位
- 参考: Paul Randal氏のI/O分析手法
  - https://www.sqlskills.com/blogs/paul/how-to-examine-io-subsystem-latencies-from-within-sql-server/
  - https://www.sqlskills.com/blogs/paul/capturing-io-latencies-period-time/

---

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

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

### 推奨読解順序

#### Step 1: SQLクエリを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaIoLatency.ps1 | `public/Get-DbaIoLatency.ps1` | BEGINブロックのSQLクエリ定義 |

**主要処理フロー**:
1. **101-152行目**: SQLクエリ定義（レイテンシ・スループット計算）
2. **102-115行目**: 基本カラムの選択
3. **117-148行目**: 計算フィールド（ReadLatency, WriteLatency, Latency, AvgBPer*）
4. **149-152行目**: sys.dm_io_virtual_file_stats と sys.master_files の結合
5. **156行目**: 除外カラムの定義

**読解のコツ**:
- CASE文でゼロ除算を防止している
- sys.dm_io_virtual_file_stats(NULL, NULL)で全ファイルを取得
- 計算済みのレイテンシ値はデフォルト表示から除外されるが、Select-Object *で確認可能

#### Step 2: 処理フローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaIoLatency.ps1 | `public/Get-DbaIoLatency.ps1` | processブロックの実行フロー |

**主要処理フロー**:
- **159行目**: Test-FunctionInterruptで中断チェック
- **162行目**: Connect-DbaInstance -MinimumVersion 9で接続
- **167-192行目**: クエリ結果をPSCustomObjectに変換
- **192行目**: Select-DefaultView -ExcludePropertyで出力制御

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

```
Get-DbaIoLatency
    │
    ├─ Test-FunctionInterrupt (中断チェック)
    │
    ├─ Connect-DbaInstance -MinimumVersion 9
    │
    ├─ $server.Query($sql)
    │      └─ sys.dm_io_virtual_file_stats + sys.master_files
    │
    └─ Select-DefaultView (出力フォーマット)
           └─ $excludeColumnsで一部プロパティ除外
```

### データフロー図

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

SqlInstance    ───▶  Connect-DbaInstance       ───▶
                           │
                     SQLクエリ実行             ───▶  sys.dm_io_virtual_file_stats
                           │                         sys.master_files
                     レイテンシ計算            ───▶
                           │
                     PSCustomObject変換        ───▶  パイプライン出力
                           │                        (DatabaseName,
                     Select-DefaultView        ───▶   FileId, PhysicalName,
                                                      IoStall, NumberOfReads,
                                                      NumberOfwrites, ...)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaIoLatency.ps1 | `public/Get-DbaIoLatency.ps1` | ソース | メイン関数定義 |
| Get-DbaIoLatency.Tests.ps1 | `tests/Get-DbaIoLatency.Tests.ps1` | テスト | 単体・統合テスト |
