# 機能設計書 279-Get-DbaDbSnapshot

## 概要

本ドキュメントは、データベーススナップショットとそのソースデータベース、作成日時、ディスク使用量を取得するdbatools PowerShellコマンド`Get-DbaDbSnapshot`の機能設計書です。

### 本機能の処理概要

`Get-DbaDbSnapshot`は、SQL Serverインスタンス上のすべてのデータベーススナップショットに関する情報を収集し、各スナップショットがどのデータベースから作成されたか、いつ作成されたか、どのくらいのディスク領域を消費しているかを表示します。これはスナップショット管理、クリーンアップ活動、およびポイントインタイムデータベースコピーのストレージ使用量の監視に役立ちます。

**業務上の目的・背景**：データベーススナップショットは、特定の時点でのデータベースの読み取り専用ビューを提供し、テスト、レポート、または迅速なロールバックに使用されます。DBAは定期的にスナップショットの存在、ソース、サイズを確認し、不要なスナップショットをクリーンアップする必要があります。本コマンドはこの管理作業を効率化します。

**機能の利用シーン**：
- スナップショットインベントリの確認
- ストレージ使用量の監視
- スナップショットのクリーンアップ前の確認
- 特定のソースデータベースのスナップショット一覧取得

**主要な処理内容**：
1. SQL Serverインスタンスへの接続
2. DatabaseSnapshotBaseNameを持つデータベースのフィルタリング
3. 各種フィルタの適用（Database, Snapshot, Exclude*）
4. fn_virtualfilestatsでディスク使用量取得
5. 結果をカスタムプロパティ付きで出力

**関連システム・外部連携**：SMO (SQL Server Management Objects) を使用し、fn_virtualfilestats関数でディスク使用量を計算します。

**権限による制御**：VIEW DATABASE STATE権限またはサーバーレベルのVIEW SERVER STATE権限が必要です。

## 関連画面

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

## 機能種別

データ取得（SELECT操作）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | Yes | 対象SQL Serverインスタンス | Mandatory, ValueFromPipeline |
| SqlCredential | PSCredential | No | 代替認証情報 | Windows/SQL認証対応 |
| Database | object[] | No | ソースデータベース名フィルタ | - |
| ExcludeDatabase | object[] | No | 除外ソースデータベース名 | - |
| Snapshot | object[] | No | スナップショット名フィルタ | - |
| ExcludeSnapshot | object[] | No | 除外スナップショット名 | - |
| EnableException | switch | No | 例外処理の有効化 | - |

### 入力データソース

- SQL Serverインスタンスへの接続情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverのコンピュータ名 |
| InstanceName | string | インスタンス名 |
| SqlInstance | string | 完全修飾インスタンス名 |
| Name | string | スナップショット名 |
| SnapshotOf | string | ソースデータベース名（DatabaseSnapshotBaseNameのエイリアス） |
| CreateDate | DateTime | スナップショット作成日時 |
| DiskUsage | dbasize | スナップショットのディスク使用量 |

### 出力先

パイプライン出力（Microsoft.SqlServer.Management.Smo.Database オブジェクト、カスタムプロパティ付き）

## 処理フロー

### 処理シーケンス

```
1. SqlInstanceパラメータのループ処理
   └─ 各インスタンスに対して処理を実行
2. Connect-DbaInstanceで接続
   └─ MinimumVersion=9（SQL Server 2005以上）
3. DatabaseSnapshotBaseNameを持つデータベースをフィルタリング
   └─ スナップショットのみを抽出
4. Databaseフィルタ適用（指定時）
   └─ ソースデータベース名でフィルタ
5. ExcludeDatabaseフィルタ適用（指定時）
   └─ ソースデータベース名で除外
6. Snapshotフィルタ適用（指定時）
   └─ スナップショット名でフィルタ
7. IsDatabaseSnapshot確認とソート（フィルタ未指定時）
   └─ DatabaseSnapshotBaseName, Nameでソート
8. ExcludeSnapshotフィルタ適用（指定時）
   └─ スナップショット名で除外
9. fn_virtualfilestatsでディスク使用量取得
   └─ BytesOnDiskを合計
10. カスタムプロパティ追加と出力
    └─ Add-Memberでプロパティ追加後、Select-DefaultView
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[SqlInstanceループ]
    B --> C[Connect-DbaInstance]
    C --> D{接続成功?}
    D -->|No| E[Stop-Function]
    D -->|Yes| F[DatabaseSnapshotBaseNameフィルタ]
    F --> G{Database指定?}
    G -->|Yes| H[ソースDBフィルタ]
    G -->|No| I{ExcludeDatabase指定?}
    H --> I
    I -->|Yes| J[ソースDB除外]
    I -->|No| K{Snapshot指定?}
    J --> K
    K -->|Yes| L[スナップショット名フィルタ]
    K -->|No| M{フィルタ未指定?}
    L --> N{ExcludeSnapshot指定?}
    M -->|Yes| O[IsDatabaseSnapshot確認<br/>ソート]
    M -->|No| N
    O --> N
    N -->|Yes| P[スナップショット除外]
    N -->|No| Q[スナップショットループ]
    P --> Q
    Q --> R[fn_virtualfilestats実行]
    R --> S[Add-Memberでプロパティ追加]
    S --> T[Select-DefaultView出力]
    T --> U[次のスナップショット]
    U --> V{次あり?}
    V -->|Yes| Q
    V -->|No| W{次のインスタンス<br/>あり?}
    W -->|Yes| B
    W -->|No| X[終了]
    E --> W
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-279-01 | 最小バージョン | SQL Server 2005（バージョン9）以上が必要 | 常時 |
| BR-279-02 | スナップショット識別 | DatabaseSnapshotBaseNameプロパティでスナップショットを識別 | 常時 |
| BR-279-03 | デフォルトソート | フィルタ未指定時はDatabaseSnapshotBaseName, Nameでソート | フィルタ未指定時 |
| BR-279-04 | ディスク使用量計算 | fn_virtualfilestatsのBytesOnDiskを合計 | 常時 |

### 計算ロジック

ディスク使用量の計算:
```sql
SELECT SUM(BytesOnDisk) AS BytesOnDisk
FROM fn_virtualfilestats(DB_ID(), NULL) S
JOIN sys.databases D ON D.database_id = S.dbid
```

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

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

| 操作 | 対象 | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ディスク使用量取得 | fn_virtualfilestats | SELECT | BytesOnDiskの合計取得 |

### SQL文（内部で実行）

#### ディスク使用量取得
```sql
SELECT SUM(BytesOnDisk) AS BytesOnDisk
FROM fn_virtualfilestats(DB_ID(), NULL) S
JOIN sys.databases D ON D.database_id = S.dbid
```

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ConnectionError | インスタンス接続失敗 | Stop-Function -Continue |
| - | QueryError | fn_virtualfilestats失敗 | Stop-Function -Continue |

### リトライ仕様

リトライ処理なし。エラー発生時はStop-Function -Continueで次のスナップショットを処理。

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

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

## パフォーマンス要件

- SMOオブジェクトのキャッシュを活用
- パイプライン処理による即座のオブジェクト出力

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

- VIEW DATABASE STATE権限またはVIEW SERVER STATE権限が必要
- PSCredentialによる安全な認証情報管理

## 備考

- SQL Server 2005以降で利用可能
- スナップショットはポイントインタイムの読み取り専用ビュー
- DiskUsageはdbasize型でフォーマット済み（KB, MB, GB等）

---

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

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

### 推奨読解順序

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

出力オブジェクトの構造とカスタムプロパティを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaDbSnapshot.ps1 | `public/Get-DbaDbSnapshot.ps1` | 128-132行目: Add-Memberでカスタムプロパティ追加 |
| 1-2 | Get-DbaDbSnapshot.ps1 | `public/Get-DbaDbSnapshot.ps1` | 132行目: dbasize型でディスク使用量フォーマット |

**読解のコツ**: DatabaseSnapshotBaseNameプロパティがスナップショットとソースデータベースを紐付けるキーです。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaDbSnapshot.ps1 | `public/Get-DbaDbSnapshot.ps1` | 関数全体の構造（139行） |

**主要処理フロー**:
1. **91行目**: CmdletBinding
2. **92-101行目**: パラメータ定義（7個）
3. **102行目**: process ブロック開始
4. **103-108行目**: インスタンスループと接続
5. **109行目**: DatabaseSnapshotBaseNameフィルタ
6. **110-124行目**: 各種フィルタ処理
7. **125-136行目**: スナップショットループとプロパティ追加
8. **127行目**: fn_virtualfilestatsクエリ
9. **132行目**: dbasize型でDiskUsage作成

#### Step 3: フィルタ処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaDbSnapshot.ps1 | `public/Get-DbaDbSnapshot.ps1` | 110-124行目: Where-Objectチェーン |

**フィルタ処理の順序**:
1. **110-112行目**: Database指定 → DatabaseSnapshotBaseNameでフィルタ
2. **113-115行目**: ExcludeDatabase指定 → DatabaseSnapshotBaseNameで除外
3. **116-118行目**: Snapshot指定 → Nameでフィルタ
4. **119-121行目**: 両方未指定 → IsDatabaseSnapshot確認 + ソート
5. **122-124行目**: ExcludeSnapshot指定 → Nameで除外

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

```
Get-DbaDbSnapshot
    │
    └─ foreach ($instance in $SqlInstance)
           │
           ├─ Connect-DbaInstance -MinimumVersion 9
           │
           ├─ $server.Databases フィルタチェーン
           │      ├─ Where-Object DatabaseSnapshotBaseName
           │      ├─ [Database] Where-Object 含む
           │      ├─ [ExcludeDatabase] Where-Object 含まない
           │      ├─ [Snapshot] Where-Object 含む
           │      ├─ [!Snapshot & !Database] IsDatabaseSnapshot + Sort
           │      └─ [ExcludeSnapshot] Where-Object 含まない
           │
           └─ foreach ($db in $dbs)
                  │
                  ├─ $db.Query("SELECT SUM(BytesOnDisk)...")
                  │
                  ├─ Add-Member -Force
                  │      ├─ ComputerName
                  │      ├─ InstanceName
                  │      ├─ SqlInstance
                  │      └─ DiskUsage ([dbasize])
                  │
                  └─ Select-DefaultView 出力
```

### データフロー図

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

SqlInstance ───────▶ Connect-DbaInstance ──────▶ Server Object
                            │
                            ▼
                    $server.Databases
                            │
                            ▼
                    DatabaseSnapshotBaseNameフィルタ
                            │
                            ▼
Database ──────────▶ ソースDBフィルタ
ExcludeDatabase ───▶ ソースDB除外
                            │
                            ▼
Snapshot ──────────▶ スナップショット名フィルタ
ExcludeSnapshot ───▶ スナップショット除外
                            │
                            ▼
                    fn_virtualfilestats
                    (BytesOnDisk)
                            │
                            ▼
                    Add-Member
                    (DiskUsage as dbasize) ──────▶ Database Objects
                            │
                            ▼
                    Select-DefaultView ──────────▶ 出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaDbSnapshot.ps1 | `public/Get-DbaDbSnapshot.ps1` | ソース | メイン機能実装（139行） |
| Get-DbaDbSnapshot.Tests.ps1 | `tests/Get-DbaDbSnapshot.Tests.ps1` | テスト | 単体テスト |
| New-DbaDbSnapshot.ps1 | `public/New-DbaDbSnapshot.ps1` | ソース | スナップショット作成 |
| Remove-DbaDbSnapshot.ps1 | `public/Remove-DbaDbSnapshot.ps1` | ソース | スナップショット削除 |
| Restore-DbaDbSnapshot.ps1 | `public/Restore-DbaDbSnapshot.ps1` | ソース | スナップショットから復元 |
