# 機能設計書 148-Get-DbaSuspectPage

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおける`Get-DbaSuspectPage`コマンドレットの機能設計を定義する。本機能は、msdbデータベースのsuspect_pagesテーブルから破損ページ情報を取得し、データベース破損の検出と分析を支援する。

### 本機能の処理概要

`Get-DbaSuspectPage`は、msdb.dbo.suspect_pagesシステムテーブルをクエリして、チェックサムエラー、トーンページ、I/Oエラーなどの破損イベントが発生したデータベースページを特定するコマンドレットである。SQL Serverは読み取り操作中に破損ページを検出すると自動的にこのテーブルに記録するため、本機能は事前予防的な破損監視とトラブルシューティングに不可欠である。

**業務上の目的・背景**：データベースの破損は深刻な問題であり、早期検出と対応が重要である。suspect_pagesテーブルはSQL Serverが自動的に維持する破損ページの記録であり、定期的な監視により潜在的な問題を早期に発見できる。本機能は、複数インスタンスの一括監視、特定データベースへのフォーカス、破損イベントの詳細分析を容易にする。

**機能の利用シーン**：
- 定期的なデータベース健全性チェック
- データベース破損のトラブルシューティング
- DBCC CHECKDBエラー後の詳細分析
- バックアップ/リストア前の破損確認
- ストレージ障害調査
- コンプライアンス監査のための破損記録確認

**主要な処理内容**：
1. Connect-DbaInstanceでSQL Serverに接続（最小バージョン9=SQL 2005以降）
2. msdb.dbo.suspect_pagesテーブルにT-SQLクエリを発行
3. event_typeコードを人間可読な形式に変換
4. Databaseパラメータ指定時はDBNameでフィルタリング
5. PSCustomObjectとして結果を出力

**関連システム・外部連携**：
- SQL Server msdbシステムデータベース
- suspect_pagesシステムテーブル
- Connect-DbaInstance（SQL Server接続）

**権限による制御**：msdbデータベースのsuspect_pagesテーブルへの読み取り権限が必要。通常はdb_owner、db_datareader、または個別のSELECT権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLIコマンド | 主機能 | 破損ページ情報取得 |

## 機能種別

情報取得処理

## 入力仕様

### 入力パラメータ

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

### 入力データソース

- msdb.dbo.suspect_pagesシステムテーブル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverホストのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| Database | string | 破損ページを含むデータベース名 |
| FileId | int | 破損ページが存在するファイルID |
| PageId | int | 破損ページのページID |
| EventType | string | 破損イベント種別（下記参照） |
| ErrorCount | int | このページが破損として検出された回数 |
| LastUpdateDate | datetime | 最終検出日時 |

### EventType値

| コード | 説明 |
|--------|------|
| 823 or 824 | I/Oエラー（event_type=1） |
| Bad Checksum | チェックサムエラー（event_type=2） |
| Torn Page | トーンページ（event_type=3） |
| Restored | リストア済み（event_type=4） |
| Repaired (DBCC) | DBCCで修復済み（event_type=5） |
| Deallocated (DBCC) | DBCCで解放済み（event_type=7） |

### 出力先

パイプライン（PSCustomObject）

## 処理フロー

### 処理シーケンス

```
1. SqlInstanceループ開始
   └─ 各インスタンスに対して処理
2. SQL Server接続
   └─ Connect-DbaInstance -MinimumVersion 9
3. T-SQLクエリ実行
   └─ msdb.dbo.suspect_pagesをSELECT
4. event_type変換
   └─ CASE文で人間可読形式に変換
5. 結果フィルタリング（Database指定時）
   └─ Where-Object DBName -EQ $Database
6. PSCustomObject構築・出力
   └─ 各行をオブジェクトとして出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[SqlInstanceループ]
    B --> C[Connect-DbaInstance<br/>-MinimumVersion 9]
    C --> D{接続成功?}
    D -->|No| E[Stop-Function:<br/>接続エラー]
    D -->|Yes| F[T-SQLクエリ実行<br/>msdb.dbo.suspect_pages]
    F --> G{クエリ成功?}
    G -->|No| H[Stop-Function:<br/>クエリエラー]
    G -->|Yes| I{Database<br/>指定あり?}
    I -->|Yes| J[DBNameで<br/>フィルタリング]
    I -->|No| K[フィルタなし]
    J --> L[結果ループ]
    K --> L
    L --> M[PSCustomObject構築]
    M --> N[パイプライン出力]
    N --> O{次の行あり?}
    O -->|Yes| L
    O -->|No| P{次のInstance<br/>あり?}
    P -->|Yes| B
    P -->|No| Q[終了]
    E --> P
    H --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 最小バージョン | SQL Server 2005（バージョン9）以降が必要 | 接続時 |
| BR-002 | event_type変換 | 数値コードを人間可読な文字列に変換 | 結果出力時 |
| BR-003 | フィルタ位置 | Databaseフィルタはクエリ後のPowerShellで実行 | Database指定時 |
| BR-004 | 空結果 | suspect_pagesが空の場合は何も返さない | 破損ページなし |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 破損ページ取得 | msdb.dbo.suspect_pages | SELECT | 破損ページ情報の読み取り |

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

#### msdb.dbo.suspect_pages

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | database_id | DB_NAME()で名前に変換 | - |
| SELECT | file_id | そのまま取得 | - |
| SELECT | page_id | そのまま取得 | - |
| SELECT | event_type | CASE文で文字列変換 | 1-7の値 |
| SELECT | error_count | そのまま取得 | - |
| SELECT | last_update_date | そのまま取得 | - |

### 実行SQL

```sql
SELECT
    DB_NAME(database_id) AS DBName,
    file_id,
    page_id,
    CASE event_type
        WHEN 1 THEN '823 or 824'
        WHEN 2 THEN 'Bad Checksum'
        WHEN 3 THEN 'Torn Page'
        WHEN 4 THEN 'Restored'
        WHEN 5 THEN 'Repaired (DBCC)'
        WHEN 7 THEN 'Deallocated (DBCC)'
    END AS EventType,
    error_count,
    last_update_date
FROM msdb.dbo.suspect_pages
```

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 接続エラー | SQL Server接続失敗 | 接続情報・ネットワーク確認 |
| - | バージョンエラー | SQL Server 2000以前 | SQL Server 2005以降に更新 |
| - | クエリエラー | suspect_pagesへのアクセス失敗 | 権限確認 |
| - | 権限エラー | msdbへのアクセス権限不足 | 適切な権限付与 |

### リトライ仕様

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

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

読み取り専用のためトランザクション制御なし。

## パフォーマンス要件

- suspect_pagesテーブルは通常小さいため、クエリは高速
- 複数インスタンス指定時は順次処理

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

- msdbデータベースへのSELECT権限が必要
- 返される情報にはデータベース名、ファイルID、ページIDが含まれる（機密性低）
- SqlCredentialパラメータで安全に認証情報を渡せる

## 備考

- suspect_pagesテーブルは最大1000行まで保持される（SQL Server制限）
- event_type=6は未使用
- 破損ページが検出された場合は、DBCC CHECKDBの実行を推奨
- 繰り返し検出される場合はハードウェア問題の可能性

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaSuspectPage.ps1 | `public/Get-DbaSuspectPage.ps1` | 出力PSCustomObject構造 |

**読解のコツ**: 111-121行目で定義される出力オブジェクトは9プロパティを持つ。EventTypeはT-SQL内でCASE文により変換済み。

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

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

**主要処理フロー**:
1. **75-81行目**: processブロック、SqlInstanceループ開始
2. **77-81行目**: Connect-DbaInstance -MinimumVersion 9
3. **83-97行目**: T-SQLクエリ定義（event_type CASE変換含む）
4. **99-103行目**: $server.Query($sql)実行、エラーハンドリング
5. **105-107行目**: Databaseパラメータによるフィルタリング
6. **110-122行目**: 結果ループとPSCustomObject出力

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaSuspectPage.ps1 | `public/Get-DbaSuspectPage.ps1` | SQLクエリ構造 |

**主要処理フロー**:
- **83-84行目**: DB_NAME(database_id)でデータベース名取得
- **85-86行目**: file_id, page_id取得
- **87-94行目**: event_type CASE変換（1-7の値を文字列に）
- **95-97行目**: error_count, last_update_date取得

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

```
Get-DbaSuspectPage
    │
    ├─ Connect-DbaInstance
    │      └─ -MinimumVersion 9（SQL 2005以降）
    │
    ├─ $server.Query($sql)
    │      └─ msdb.dbo.suspect_pages SELECT
    │
    ├─ Where-Object（Databaseフィルタ）
    │
    └─ PSCustomObject出力
           ├─ ComputerName
           ├─ InstanceName
           ├─ SqlInstance
           ├─ Database
           ├─ FileId
           ├─ PageId
           ├─ EventType
           ├─ ErrorCount
           └─ LastUpdateDate
```

### データフロー図

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

SqlInstance ────▶ Connect-DbaInstance
                        │
                        ▼
                  SMO Server Object
                        │
                        ▼
                  T-SQL Query
                  msdb.dbo.suspect_pages
                        │
                        ▼
                  DataTable結果
                        │
Database ───────▶ Where-Object
(オプション)      DBName -EQ $Database
                        │
                        ▼
                  foreach行ループ
                        │
                        ▼
                  [PSCustomObject]
                  - ComputerName
                  - InstanceName
                  - SqlInstance
                  - Database
                  - FileId
                  - PageId
                  - EventType (変換済)
                  - ErrorCount
                  - LastUpdateDate
```

### 関連ファイル一覧

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