# 機能設計書 409-Get-DbaMemoryCondition

## 概要

本ドキュメントは、SQL Serverのリソースモニターリングバッファからメモリ圧迫通知と使用率メトリクスを取得する`Get-DbaMemoryCondition`機能について記述する。

### 本機能の処理概要

**業務上の目的・背景**：SQL Serverは内部的にメモリ状態を監視し、メモリ圧迫イベントをリングバッファに記録している。これらのイベントには、物理メモリ不足、ページファイル不足、仮想アドレス空間不足などの重要な通知が含まれる。本機能は、これらのメモリ圧迫イベントと詳細なメモリ使用率メトリクスを取得することで、DBAがメモリ不足、過剰なページング、自動メモリ調整をトリガーするメモリ圧迫状態に起因するパフォーマンス問題を診断できるようにする。

**機能の利用シーン**：
- メモリ不足によるパフォーマンス問題の診断時
- メモリ圧迫イベントと特定の時間帯の相関分析時
- 物理メモリ、ページファイル、仮想アドレス空間の使用率監視時
- SQL Serverのメモリ割り当て状況の確認時

**主要な処理内容**：
1. 指定されたSQL Serverインスタンスへの接続確立
2. RING_BUFFER_RESOURCE_MONITORからXMLデータを取得
3. メモリ関連の通知と使用率メトリクスをXMLからパース
4. NotificationTimeの計算（リングバッファタイムスタンプから）
5. 詳細なメモリ統計を含む結果オブジェクトの出力

**関連システム・外部連携**：SQL Serverの動的管理ビュー`sys.dm_os_ring_buffers`および`sys.dm_os_sys_info`を参照する。Microsoftサポート提供のクエリに基づく。

**権限による制御**：VIEW SERVER STATE権限またはsysadminロールが必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | コマンドライン | 主画面 | PowerShellコンソールからの直接実行 |

## 機能種別

データ取得（メモリ診断）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstance[] | Yes | 対象のSQL Serverインスタンス | DbaInstance型による検証 |
| SqlCredential | PSCredential | No | SQL Server認証用の資格情報 | PowerShell資格情報オブジェクト |
| EnableException | switch | No | 例外処理を有効化 | - |

### 入力データソース

- PowerShellコマンドライン入力
- パイプライン入力（SqlInstance）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverインスタンスのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全修飾SQL Serverインスタンス名 |
| Runtime | DateTime | クエリが実行された日時 |
| NotificationTime | DateTime | メモリ圧迫イベントが発生した計算日時 |
| NotificationType | string | メモリ通知の種類（Low Physical Memory等） |
| MemoryUtilizationPercent | int | 現在のメモリ使用率（0-100%） |
| TotalPhysicalMemory | DbaSize | 物理RAM総量 |
| AvailablePhysicalMemory | DbaSize | 利用可能な物理RAM |
| TotalPageFile | DbaSize | ページファイル総サイズ |
| AvailablePageFile | DbaSize | 利用可能なページファイルサイズ |
| TotalVirtualAddressSpace | DbaSize | 仮想アドレス空間総量 |
| AvailableVirtualAddressSpace | DbaSize | 利用可能な仮想アドレス空間 |
| NodeId | bigint | NUMAノード識別子 |
| SQLReservedMemory | DbaSize | SQL Server予約メモリ |
| SQLCommittedMemory | DbaSize | SQL Serverコミット済みメモリ |
| RecordId | bigint | リングバッファのレコード識別子 |
| Type | string | リングバッファのレコードタイプ |
| Indicators | bigint | メモリ圧迫インジケータ値（ビットフラグ） |
| RecordTime | bigint | リングバッファレコードタイムスタンプ（ミリ秒） |
| CurrentTime | bigint | 現在のシステム時刻（ms_ticks） |

### 出力先

PowerShellパイプライン（PSCustomObject）

## 処理フロー

### 処理シーケンス

```
1. SQLクエリ準備（beginブロック）
   └─ RING_BUFFER_RESOURCE_MONITORからのXML解析クエリ構築
   └─ NotificationTime計算ロジックを含む

2. 各インスタンスに対してループ処理
   └─ Connect-DbaInstanceによる接続確立（MinimumVersion 9）
   └─ 接続失敗時はStop-Functionで継続処理

3. SQLクエリ実行
   └─ リングバッファXMLデータの解析

4. 結果オブジェクト出力
   └─ メモリサイズはDbaSize型に変換（KB→バイト）
   └─ RecordTime昇順でソート
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[SQLクエリ準備]
    B --> C{各インスタンスでループ}
    C --> D[Connect-DbaInstance]
    D --> E{接続成功?}
    E -->|No| F[Stop-Function -Continue]
    F --> C
    E -->|Yes| G[SQLクエリ実行]
    G --> H{クエリ成功?}
    H -->|No| I[Stop-Function]
    H -->|Yes| J{各レコードでループ}
    J --> K[PSCustomObject生成]
    K --> L[DbaSize変換]
    L --> M[パイプライン出力]
    M --> J
    J -->|ループ終了| C
    C -->|ループ終了| N[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | バージョン要件 | SQL Server 2005以上が必要 | 接続時に検証 |
| BR-002 | KB→バイト変換 | すべてのメモリサイズはKBからバイトに変換 | DbaSize型出力時 |
| BR-003 | 時刻計算 | NotificationTimeはリングバッファタイムスタンプから計算 | 各レコードに対して |
| BR-004 | ソート順 | 結果はRecordTime昇順でソート | 常時適用 |

### 計算ロジック

- NotificationTime計算:
  ```sql
  DATEADD(MILLISECOND,
    -1 * CONVERT(BIGINT, (sys.ms_ticks - sys.s_ticks*1000) - (a.[RecordTime] - a.[RecordTime_S]*1000)),
    DATEADD(SECOND, -1 * (sys.s_ticks - a.[RecordTime_S]), GETDATE()))
  ```
- メモリサイズ変換: `[dbasize]$row.xxxKB * 1024`

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| リングバッファ取得 | sys.dm_os_ring_buffers | SELECT | RING_BUFFER_RESOURCE_MONITORデータ取得 |
| システム情報取得 | sys.dm_os_sys_info | SELECT | ms_ticks取得（時刻計算用） |

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

#### sys.dm_os_ring_buffers

| 操作 | 項目（カラム名） | 取得条件 | 備考 |
|-----|-----------------|---------|------|
| SELECT | record | ring_buffer_type = 'RING_BUFFER_RESOURCE_MONITOR' | XMLとして解析 |

#### XMLパース対象要素

| XPath | 取得内容 |
|-------|---------|
| (//Record/ResourceMonitor/Notification)[1] | NotificationType |
| (//Record/MemoryRecord/MemoryUtilization)[1] | MemoryUtilizationPercent |
| (//Record/MemoryRecord/TotalPhysicalMemory)[1] | TotalPhysicalMemoryKB |
| (//Record/MemoryRecord/AvailablePhysicalMemory)[1] | AvailablePhysicalMemoryKB |
| (//Record/MemoryRecord/TotalPageFile)[1] | TotalPageFileKB |
| (//Record/MemoryRecord/AvailablePageFile)[1] | AvailablePageFileKB |
| (//Record/MemoryRecord/TotalVirtualAddressSpace)[1] | TotalVirtualAddressSpaceKB |
| (//Record/MemoryRecord/AvailableVirtualAddressSpace)[1] | AvailableVirtualAddressSpaceKB |
| (//Record/MemoryNode/@id)[1] | NodeId |
| (//Record/MemoryNode/ReservedMemory)[1] | SQLReservedMemoryKB |
| (//Record/MemoryNode/CommittedMemory)[1] | SQLCommittedMemoryKB |
| (//Record/@id)[1] | RecordId |
| (//Record/@type)[1] | Type |
| (//Record/ResourceMonitor/Indicators)[1] | Indicators |
| (//Record/@time)[1] | RecordTime |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ConnectionError | SQL Serverへの接続失敗 | Stop-Functionで処理継続 |
| - | QueryError | SQLクエリ実行失敗 | Stop-Functionでエラーメッセージ出力 |
| - | VersionError | SQL Server 2005未満 | MinimumVersionで接続拒否 |

### リトライ仕様

自動リトライなし。

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

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

## パフォーマンス要件

- リングバッファからのデータ取得のため軽量
- 結果数はリングバッファに記録されたイベント数に依存

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

- VIEW SERVER STATE権限またはsysadminロールが必要
- SqlCredentialパラメータでSQL認証を使用可能

## 備考

- Microsoftサポート提供のクエリに基づいた実装
- Out-GridViewと組み合わせてグラフィカルな表示が可能
- DbaSize型によりKB、MB、GB、TBなどの単位で自動フォーマット

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaMemoryCondition.ps1 | `public/Get-DbaMemoryCondition.ps1` | 156-178行目の出力オブジェクト定義 |

**読解のコツ**: メモリサイズはすべてKBからバイトに変換してDbaSize型として出力される。

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

処理の起点となる関数定義とパラメータを特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaMemoryCondition.ps1 | `public/Get-DbaMemoryCondition.ps1` | 1-85行目のヘルプドキュメントとパラメータ定義 |

**主要処理フロー**:
1. **79-85行目**: パラメータ定義

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

リングバッファからメモリ情報を取得するSQLクエリ。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaMemoryCondition.ps1 | `public/Get-DbaMemoryCondition.ps1` | 88-140行目のbeginブロック |

**主要処理フロー**:
- **88-107行目**: 出力カラムとNotificationTime計算
- **109-127行目**: XML解析サブクエリ
- **128-140行目**: システム情報との結合

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

```
Get-DbaMemoryCondition
    │
    ├─ Connect-DbaInstance (内部関数)
    │      └─ SQL Server接続確立
    │
    └─ $server.Query() (SMOメソッド)
           └─ リングバッファクエリ実行
                  └─ XML解析
                  └─ 時刻計算
```

### データフロー図

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

SqlInstance ───────────▶ Connect-DbaInstance ──────▶ $server
                                 │
SqlCredential ───────────────────┘
                                 │
                                 ▼
                         SQLクエリ実行
                         (リングバッファ取得)
                                 │
                                 ▼
                         XML解析
                         (メモリメトリクス抽出)
                                 │
                                 ▼
                         NotificationTime計算
                                 │
                                 ▼
                         DbaSize変換 ────────────▶ パイプライン出力
                         (KB→バイト)

出力プロパティ:
- ComputerName, InstanceName, SqlInstance
- Runtime, NotificationTime, NotificationType
- MemoryUtilizationPercent
- TotalPhysicalMemory, AvailablePhysicalMemory
- TotalPageFile, AvailablePageFile
- TotalVirtualAddressSpace, AvailableVirtualAddressSpace
- NodeId, SQLReservedMemory, SQLCommittedMemory
- RecordId, Type, Indicators, RecordTime, CurrentTime
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaMemoryCondition.ps1 | `public/Get-DbaMemoryCondition.ps1` | ソース | メイン機能実装 |
| Get-DbaMemoryCondition.Tests.ps1 | `tests/Get-DbaMemoryCondition.Tests.ps1` | テスト | Pesterユニットテスト |
