# 機能設計書 47-Restore-DbaDbSnapshot

## 概要

本ドキュメントは、データベーススナップショットからSQL Serverデータベースをリストアするdbatools PowerShellコマンド `Restore-DbaDbSnapshot` の機能設計書である。

### 本機能の処理概要

この機能は、SQL Serverデータベースをスナップショット作成時の状態に正確に復元し、スナップショット以降に加えられた全ての変更を破棄する。開発データベースのテスト後のロールバック、問題のある変更の取り消し、バックアップファイルからのリストアなしで既知の良好な状態への復帰に特に有用である。

**業務上の目的・背景**：データベース変更のテスト後に素早く元の状態に戻したい場合や、本番環境で問題が発生した際に特定時点に戻したい場合がある。スナップショットからのリストアはバックアップからのリストアより高速で、ダウンタイムを最小化できる。

**機能の利用シーン**：
- 開発/テスト環境でのテスト後のデータベースリセット
- 本番環境での問題発生時の緊急ロールバック
- データ検証テスト後の状態復元
- 変更スクリプト実行後の確認と取り消し

**主要な処理内容**：
1. スナップショットの特定と検証
2. 同一データベースの他のスナップショット削除（必須）
3. アクティブ接続の切断（Force指定時）
4. RESTORE DATABASE FROM DATABASE_SNAPSHOT実行
5. ログファイル設定の復元（SQL Serverバグ対策）

**関連システム・外部連携**：なし（SQL Server内部操作）

**権限による制御**：対象データベースへのRESTORE権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | CLIベースの運用コマンド |

## 機能種別

データベースリストア / ポイントインタイムリカバリ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstance[] | No | 対象SQL Serverインスタンス | - |
| SqlCredential | PSCredential | No | 代替認証情報 | - |
| Database | object[] | No | リストア対象データベース名 | - |
| ExcludeDatabase | object[] | No | 除外するデータベース名 | - |
| Snapshot | object[] | No | リストア元スナップショット名 | - |
| InputObject | Microsoft.SqlServer.Management.Smo.Database[] | No | パイプラインからのスナップショットオブジェクト | - |
| Force | switch | No | 他のスナップショット削除とアクティブ接続切断を強制 | - |
| EnableException | switch | No | 例外を有効にするスイッチ | - |
| WhatIf | switch | No | 実行せずに何が起きるか表示 | - |
| Confirm | switch | No | 確認プロンプト表示 | - |

### 入力データソース

Get-DbaDbSnapshot出力またはパラメータ指定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なインスタンス名 |
| Name | string | データベース名 |
| Status | string | データベースステータス |
| IsAccessible | bool | アクセス可能フラグ |
| RecoveryModel | string | 復旧モデル |
| Owner | string | データベース所有者 |
| その他 | - | SMO Database オブジェクトの全プロパティ |

### 出力先

PowerShellパイプライン（Microsoft.SqlServer.Management.Smo.Database）

## 処理フロー

### 処理シーケンス

```
1. パラメータ検証
   └─ Snapshot/Database/ExcludeDatabase/InputObjectのいずれか必須
2. スナップショット取得
   └─ Get-DbaDbSnapshotで対象スナップショット特定
3. 各スナップショットに対して処理
   ├─ IsDatabaseSnapshot検証
   ├─ IsAccessible検証
   ├─ FileStreamグループチェック
   ├─ 他のスナップショットの削除（Force時）
   └─ RESTORE DATABASE FROM DATABASE_SNAPSHOT実行
4. ログファイル設定の復元
   └─ Size, Growth, GrowthTypeの再設定
5. 結果取得
   └─ Get-DbaDatabase で復元済みDBを取得
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{Snapshot/Database/InputObject指定?}
    B -->|No| C[Stop-Function]
    B -->|Yes| D[Get-DbaDbSnapshot]
    D --> E{各スナップショットループ}
    E --> F{IsDatabaseSnapshot?}
    F -->|No| G[Stop-Function Continue]
    F -->|Yes| H{IsAccessible?}
    H -->|No| I[Stop-Function Continue]
    H -->|Yes| J{FileStreamあり?}
    J -->|Yes| K[Stop-Function Continue]
    J -->|No| L{他のスナップショットあり?}
    L -->|Yes, Force無| M[Stop-Function Continue]
    L -->|Yes, Force有| N[Remove-DbaDatabase]
    L -->|No| O[RESTORE準備]
    N --> O
    O --> P{Force?}
    P -->|Yes| Q[Stop-DbaProcess]
    P -->|No| R[RESTORE実行]
    Q --> R
    R --> S{成功?}
    S -->|No| T{デッドロック?}
    T -->|Yes, リトライ可| U[待機してリトライ]
    T -->|No| V[Stop-Function Continue]
    U --> R
    S -->|Yes| W[ログファイル設定復元]
    W --> X[Get-DbaDatabase]
    X --> E
    E --> Y[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-47-01 | 他スナップショット削除 | リストア前に同一DBの他スナップショットを削除する必要がある | SQL Server仕様 |
| BR-47-02 | FileStream制限 | FileStreamグループを含むDBはスナップショットからリストア不可 | FileStreamあり時 |
| BR-47-03 | デッドロックリトライ | デッドロック発生時は最大3回リトライ | デッドロック（エラー1205）時 |
| BR-47-04 | ログファイル復元 | リストア後にログファイルのSize/Growth/GrowthTypeを元に戻す | 常時（SQL Serverバグ対策） |

### 計算ロジック

**デッドロックリトライ待機時間（212-213行目）**:
```powershell
$waitSeconds = [Math]::Pow(2, $retryCount)  # 2, 4, 8秒の指数バックオフ
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| スナップショットリストア | データベース全体 | RESTORE | スナップショット時点に復元 |
| ログファイル設定変更 | sys.database_files | ALTER | Size/Growth/GrowthType復元 |

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

データベースレベルの操作であり、特定テーブルへの操作ではない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | パラメータエラー | 必須パラメータ未指定 | Stop-Functionで終了 |
| ConnectionError | 接続エラー | SQL Serverへの接続失敗 | Stop-Function Continueで継続 |
| - | 非スナップショット | 指定されたDBがスナップショットでない | Stop-Function Continueで継続 |
| - | アクセス不可 | スナップショットにアクセスできない | Stop-Function Continueで継続 |
| - | FileStream | FileStreamグループが含まれる | Stop-Function Continueで継続 |
| 1205 | デッドロック | リストア操作中のデッドロック | 指数バックオフでリトライ（最大3回） |

### リトライ仕様

デッドロック（エラー1205）発生時に最大3回リトライ。待機時間は指数バックオフ（2秒、4秒、8秒）。

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

SQL ServerのRESTORE DATABASE FROM DATABASE_SNAPSHOT操作はトランザクション内で自動管理される。

## パフォーマンス要件

スナップショットからのリストアはバックアップファイルからのリストアより高速。ただし、スナップショット以降の変更が多いほど時間がかかる。

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

- 対象データベースへのRESTORE権限が必要
- Forceオプション使用時は他ユーザーの接続が切断される
- ConfirmImpact = "Medium"で確認プロンプトが表示される

## 備考

- SQL Serverのバグにより、スナップショットリストア後にログファイルの増分設定がリセットされる問題に対応
- リストア後は必ずバックアップを取得し、不要になったスナップショットは削除することを推奨

---

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

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

### 推奨読解順序

#### Step 1: パラメータ定義を理解する

入力パラメータの構造を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Restore-DbaDbSnapshot.ps1 | `public/Restore-DbaDbSnapshot.ps1` | 118-129行目のparam定義 |

**読解のコツ**: Snapshot/Database/InputObjectのいずれかが必須。

#### Step 2: スナップショット取得と検証を理解する

対象スナップショットの特定と検証を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Restore-DbaDbSnapshot.ps1 | `public/Restore-DbaDbSnapshot.ps1` | 134-157行目 |

**主要処理フロー**:
- **146行目**: Get-DbaDbSnapshotでスナップショット取得
- **148-156行目**: Snapshot指定時のフィルタリング

#### Step 3: リストア前処理を理解する

他スナップショット削除とFileStreamチェックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Restore-DbaDbSnapshot.ps1 | `public/Restore-DbaDbSnapshot.ps1` | 159-191行目 |

**主要処理フロー**:
- **164-165行目**: IsDatabaseSnapshotチェック
- **168-169行目**: IsAccessibleチェック
- **172行目**: 他スナップショット検出
- **177-179行目**: FileStreamグループチェック
- **181-183行目**: Force無しで他スナップショットありの場合のエラー
- **185-189行目**: Remove-DbaDatabase で他スナップショット削除

#### Step 4: リストア実行とリトライを理解する

RESTORE実行とデッドロックリトライを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Restore-DbaDbSnapshot.ps1 | `public/Restore-DbaDbSnapshot.ps1` | 193-228行目 |

**主要処理フロー**:
- **195-198行目**: リトライループ初期化
- **200-203行目**: Force時のStop-DbaProcess
- **205行目**: RESTORE DATABASE FROM DATABASE_SNAPSHOT実行
- **208-221行目**: デッドロック時のリトライ処理

#### Step 5: ログファイル設定復元を理解する

SQL Serverバグ対策のログファイル設定復元を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Restore-DbaDbSnapshot.ps1 | `public/Restore-DbaDbSnapshot.ps1` | 231-248行目 |

**主要処理フロー**:
- **231-233行目**: ログファイルのRefresh
- **235-247行目**: Size/Growth/GrowthTypeの比較と復元

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

```
Restore-DbaDbSnapshot
    │
    ├─ Connect-DbaInstance
    │      └─ SQL Server接続確立
    │
    ├─ Get-DbaDbSnapshot
    │      └─ スナップショット取得
    │
    ├─ Remove-DbaDatabase
    │      └─ 他スナップショット削除
    │
    ├─ Stop-DbaProcess
    │      └─ アクティブ接続切断
    │
    ├─ server.Query()
    │      └─ RESTORE DATABASE FROM DATABASE_SNAPSHOT
    │
    └─ Get-DbaDatabase
           └─ リストア済みDB取得
```

### データフロー図

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

Database / Snapshot ─────────► Get-DbaDbSnapshot ──────────────►
InputObject ─────────────────►         │
                                      ▼
                              IsDatabaseSnapshot検証
                              IsAccessible検証
                              FileStreamチェック
                                      │
                                      ▼
                              他スナップショット検出
                                      │
                              {Force?}─────► Remove-DbaDatabase
                                      │
                              {Force?}─────► Stop-DbaProcess
                                      │
                                      ▼
                              RESTORE DATABASE FROM DATABASE_SNAPSHOT
                                      │
                              {デッドロック?}───► リトライ
                                      │
                                      ▼
                              ログファイル設定復元
                                      │
                                      ▼
                              Get-DbaDatabase ────► Database出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Restore-DbaDbSnapshot.ps1 | `public/Restore-DbaDbSnapshot.ps1` | ソース | メイン機能実装 |
| Restore-DbaDbSnapshot.Tests.ps1 | `tests/Restore-DbaDbSnapshot.Tests.ps1` | テスト | Pesterテストコード |
| Get-DbaDbSnapshot.ps1 | `public/Get-DbaDbSnapshot.ps1` | ソース | スナップショット取得（依存コマンド） |
| Remove-DbaDatabase.ps1 | `public/Remove-DbaDatabase.ps1` | ソース | スナップショット削除（依存コマンド） |
| Stop-DbaProcess.ps1 | `public/Stop-DbaProcess.ps1` | ソース | プロセス切断（依存コマンド） |
