# 機能設計書 149-Get-DbaTempdbUsage

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおける`Get-DbaTempdbUsage`コマンドレットの機能設計を定義する。本機能は、実行中のクエリによるTempdbの使用状況を取得し、リソース消費の監視と分析を支援する。

### 本機能の処理概要

`Get-DbaTempdbUsage`は、DMV（動的管理ビュー）をクエリして、現在実行中のセッションがTempdbでどの程度のスペースを使用しているかを詳細に返すコマンドレットである。ユーザーオブジェクト（一時テーブル等）と内部オブジェクト（ソート、ハッシュ結合等）の両方の割り当て・解放状況を追跡する。

**業務上の目的・背景**：Tempdbはすべてのデータベースで共有されるリソースであり、過剰な使用はサーバー全体のパフォーマンスに影響する。Tempdb枯渇問題のトラブルシューティング、リソース消費の大きいクエリの特定、Tempdbサイズの適正化検討において、本機能が提供するセッション別の使用状況が重要な判断材料となる。

**機能の利用シーン**：
- Tempdbサイズ急増時のトラブルシューティング
- Tempdbを大量消費しているクエリの特定
- Tempdbサイズ計画のためのベースライン取得
- パフォーマンス問題調査時のリソース使用分析
- 長時間実行クエリのTempdb影響評価

**主要な処理内容**：
1. Connect-DbaInstanceでSQL Serverに接続（最小バージョン10=SQL 2008以降）
2. sys.dm_db_session_space_usage、sys.dm_exec_sessions、sys.dm_exec_requests等のDMVを結合してクエリ
3. tempdb.sys.dm_db_task_space_usageからタスクレベルの使用状況を取得
4. sys.dm_exec_sql_textでクエリテキストを取得
5. 自セッションを除外し、Tempdb使用があるセッションのみを返す

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

**権限による制御**：VIEW SERVER STATE権限が必要。DMVへのアクセスにはサーバーレベルの権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLIコマンド | 主機能 | Tempdb使用状況取得 |

## 機能種別

情報取得処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | Yes | 対象SQL Serverインスタンス | パイプライン入力対応 |
| SqlCredential | PSCredential | No | SQL Server認証用クレデンシャル | - |
| EnableException | switch | No | 例外を有効化 | - |

### 入力データソース

- sys.dm_db_session_space_usage
- sys.dm_exec_sessions
- sys.dm_exec_requests
- tempdb.sys.dm_db_task_space_usage
- sys.dm_exec_sql_text

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | コンピュータ名 |
| InstanceName | string | インスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| Spid | int | セッションID |
| StatementCommand | string | 実行中のSQLコマンド種別 |
| QueryText | string | 実行中のT-SQLステートメント |
| ProcedureName | string | ストアドプロシージャ名（該当する場合） |
| StartTime | datetime | リクエスト開始時刻 |
| CurrentUserAllocatedKB | int | 現在のユーザーオブジェクト割り当て（KB） |
| TotalUserAllocatedKB | int | 累計ユーザーオブジェクト割り当て（KB） |
| UserDeallocatedKB | int | ユーザーオブジェクト解放（KB） |
| TotalUserDeallocatedKB | int | 累計ユーザーオブジェクト解放（KB） |
| InternalAllocatedKB | int | 内部オブジェクト割り当て（KB） |
| TotalInternalAllocatedKB | int | 累計内部オブジェクト割り当て（KB） |
| InternalDeallocatedKB | int | 内部オブジェクト解放（KB） |
| TotalInternalDeallocatedKB | int | 累計内部オブジェクト解放（KB） |
| RequestedReads | int | 物理読み取り数 |
| RequestedWrites | int | 書き込み数 |
| RequestedLogicalReads | int | 論理読み取り数 |
| RequestedCPUTime | int | CPU時間（ミリ秒） |
| IsUserProcess | bool | ユーザープロセスかどうか |
| Status | string | セッション状態 |
| Database | string | アクセス中のデータベース名 |
| LoginName | string | SQL Serverログイン名 |
| OriginalLoginName | string | 元のログイン名（偽装前） |
| NTDomain | string | Windowsドメイン名 |
| NTUserName | string | Windowsユーザー名 |
| HostName | string | クライアントホスト名 |
| ProgramName | string | クライアントプログラム名 |
| LoginTime | datetime | ログイン日時 |
| LastRequestedStartTime | datetime | 最終リクエスト開始日時 |
| LastRequestedEndTime | datetime | 最終リクエスト終了日時 |

### 出力先

パイプライン（DataRow / PSCustomObject）

## 処理フロー

### 処理シーケンス

```
1. SqlInstanceループ開始
   └─ 各インスタンスに対して処理
2. SQL Server接続
   └─ Connect-DbaInstance -MinimumVersion 10
3. DMVクエリ実行
   ├─ sys.dm_db_session_space_usage（セッション空間使用）
   ├─ INNER JOIN sys.dm_exec_sessions（セッション情報）
   ├─ LEFT JOIN sys.dm_exec_requests（リクエスト情報）
   ├─ LEFT JOIN tempdb.sys.dm_db_task_space_usage（タスク空間使用）
   └─ OUTER APPLY sys.dm_exec_sql_text（SQLテキスト）
4. フィルタリング
   ├─ 自セッション除外（@@SPID）
   └─ Tempdb使用があるセッションのみ
5. 結果出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[SqlInstanceループ]
    B --> C[Connect-DbaInstance<br/>-MinimumVersion 10]
    C --> D{接続成功?}
    D -->|No| E[Stop-Function:<br/>接続エラー]
    D -->|Yes| F[T-SQLクエリ実行<br/>DMV結合クエリ]
    F --> G[結果をパイプライン出力]
    G --> H{次のInstance<br/>あり?}
    H -->|Yes| B
    H -->|No| I[終了]
    E --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 最小バージョン | SQL Server 2008（バージョン10）以降が必要 | 接続時 |
| BR-002 | 自セッション除外 | 実行中のセッション（@@SPID）は結果から除外 | 常時 |
| BR-003 | Tempdb使用フィルタ | 割り当て-解放の差分が0でないセッションのみ出力 | 常時 |
| BR-004 | KB単位変換 | ページ数×8でKB単位に変換 | 常時 |

### 計算ロジック

- CurrentUserAllocatedKB = tdb.UserObjectAllocated * 8
- TotalUserAllocatedKB = (t.user_objects_alloc_page_count + tdb.UserObjectAllocated) * 8
- InternalAllocatedKB = tdb.InternalObjectAllocated * 8
- Tempdb使用判定 = (UserObjectAllocated - UserObjectDeallocated + InternalObjectAllocated - InternalObjectDeallocated) != 0

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| Tempdb使用取得 | sys.dm_db_session_space_usage | SELECT | セッション空間使用 |
| セッション情報取得 | sys.dm_exec_sessions | SELECT | セッション詳細 |
| リクエスト情報取得 | sys.dm_exec_requests | SELECT | 実行中リクエスト |
| タスク空間取得 | tempdb.sys.dm_db_task_space_usage | SELECT | タスク空間使用 |
| SQLテキスト取得 | sys.dm_exec_sql_text | SELECT | 実行SQLテキスト |

### 実行SQL（抜粋）

```sql
SELECT
    SERVERPROPERTY('MachineName') AS ComputerName,
    ...
    t.session_id AS Spid,
    r.command AS StatementCommand,
    SUBSTRING(est.[text], ...) AS QueryText,
    ...
    tdb.UserObjectAllocated * 8 AS CurrentUserAllocatedKB,
    ...
FROM sys.dm_db_session_space_usage AS t
INNER JOIN sys.dm_exec_sessions AS s ON s.session_id = t.session_id
LEFT JOIN sys.dm_exec_requests AS r ON r.session_id = s.session_id
LEFT JOIN (...) AS tdb ON tdb.session_id = r.session_id
OUTER APPLY sys.dm_exec_sql_text(r.[sql_handle]) AS est
WHERE t.session_id != @@SPID
AND (tdb.UserObjectAllocated - tdb.UserObjectDeallocated + ...) != 0
OPTION (RECOMPILE)
```

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 接続エラー | SQL Server接続失敗 | 接続情報・ネットワーク確認 |
| - | バージョンエラー | SQL Server 2008より前 | SQL Server 2008以降に更新 |
| - | 権限エラー | VIEW SERVER STATE権限なし | 権限付与 |

### リトライ仕様

リトライは実装されていない。エラー時はStop-Function -Continueで次のインスタンスへ。

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

読み取り専用のためトランザクション制御なし。OPTION (RECOMPILE)でプラン再生成。

## パフォーマンス要件

- DMVアクセスのためリアルタイム情報を取得
- OPTION (RECOMPILE)により毎回実行プラン生成
- 大量セッション環境では時間がかかる可能性

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

- VIEW SERVER STATE権限が必要
- 他セッションのクエリテキストが表示される（機密情報含む可能性）
- SqlCredentialパラメータで安全に認証情報を渡せる

## 備考

- Tempdb使用がないセッションは結果に含まれない
- 一時テーブル、テーブル変数、カーソル、ソート、ハッシュ結合などがTempdbを使用
- UserObject: 一時テーブル、テーブル変数など
- InternalObject: ソート、ハッシュ結合、スプールなど

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaTempdbUsage.ps1 | `public/Get-DbaTempdbUsage.ps1` | クエリ結果の列構造 |

**読解のコツ**: 101-156行目のT-SQLクエリで定義される列がそのまま出力される。$server.Query($sql)の戻り値はDataTableのため、DataRowとして出力される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaTempdbUsage.ps1 | `public/Get-DbaTempdbUsage.ps1` | 全体処理フロー |

**主要処理フロー**:
1. **93-99行目**: processブロック、Connect-DbaInstance
2. **101-156行目**: T-SQLクエリ定義
3. **101-103行目**: SERVERPROPERTY()でインスタンス情報
4. **104-137行目**: セッション・Tempdb使用情報
5. **138-156行目**: FROM句（DMV結合）とフィルタ条件
6. **158行目**: $server.Query($sql)実行

#### Step 3: DMV結合構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaTempdbUsage.ps1 | `public/Get-DbaTempdbUsage.ps1` | DMV結合ロジック |

**主要処理フロー**:
- **138行目**: sys.dm_db_session_space_usage（ベーステーブル）
- **139-140行目**: INNER JOIN sys.dm_exec_sessions（セッション詳細）
- **141-142行目**: LEFT JOIN sys.dm_exec_requests（実行中リクエスト）
- **143-152行目**: LEFT JOIN サブクエリ（タスクレベル集計）
- **153行目**: OUTER APPLY sys.dm_exec_sql_text（SQLテキスト取得）
- **154-155行目**: WHERE条件（自セッション除外、Tempdb使用あり）

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

```
Get-DbaTempdbUsage
    │
    ├─ Connect-DbaInstance
    │      └─ -MinimumVersion 10（SQL 2008以降）
    │
    └─ $server.Query($sql)
           │
           └─ DMV結合クエリ
                  ├─ sys.dm_db_session_space_usage（セッション空間）
                  ├─ sys.dm_exec_sessions（セッション情報）
                  ├─ sys.dm_exec_requests（リクエスト情報）
                  ├─ tempdb.sys.dm_db_task_space_usage（タスク空間）
                  └─ sys.dm_exec_sql_text（SQLテキスト）
```

### データフロー図

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

SqlInstance ────▶ Connect-DbaInstance
                        │
                        ▼
                  SMO Server Object
                        │
                        ▼
┌─────────────────────────────────────────────────────┐
│              T-SQL DMV結合クエリ                      │
│                                                       │
│  dm_db_session_space_usage                           │
│         │                                             │
│    INNER JOIN dm_exec_sessions                       │
│         │                                             │
│    LEFT JOIN dm_exec_requests                        │
│         │                                             │
│    LEFT JOIN (タスク空間集計サブクエリ)               │
│         │                                             │
│    OUTER APPLY dm_exec_sql_text                      │
│         │                                             │
│    WHERE @@SPID除外 AND Tempdb使用あり               │
└─────────────────────────────────────────────────────┘
                        │
                        ▼
                  [DataTable/DataRow]
                  - ComputerName
                  - InstanceName
                  - Spid
                  - QueryText
                  - CurrentUserAllocatedKB
                  - TotalUserAllocatedKB
                  - InternalAllocatedKB
                  - ...（30+プロパティ）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaTempdbUsage.ps1 | `public/Get-DbaTempdbUsage.ps1` | ソース | メイン機能 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続 |
