# 機能設計書 40-Invoke-DbaAdvancedRestore

## 概要

本ドキュメントは、dbatools PowerShellモジュールの`Invoke-DbaAdvancedRestore`コマンドレットに関する機能設計書です。このコマンドは、処理済みBackupHistoryオブジェクトから高度なカスタマイズオプションを使用してデータベースリストアを実行します。

### 本機能の処理概要

Invoke-DbaAdvancedRestoreは、dbatoolsリストアパイプラインの最終実行ステップです。事前処理されたBackupHistoryオブジェクトを受け取り、標準のRestore-DbaDatabaseコマンドでは処理できない複雑なシナリオに対応した実際のSQL Serverデータベースリストアを実行します。

**業務上の目的・背景**：標準的なリストアコマンドでは対応できない複雑なリストアシナリオ（ポイントインタイムリカバリ、ページレベルリストア、Azure/S3ストレージからのリストア、カスタムファイル再配置など）に対応するため、詳細な制御が可能なリストア機能を提供します。

**機能の利用シーン**：
- ポイントインタイムリカバリによる特定時点へのデータ復元
- ページレベルリストアによる破損ページの修復
- Azure Blob Storage/S3からのバックアップリストア
- 複雑なファイル再配置を伴うマイグレーション
- スクリプト出力による事前検証とドキュメント化
- CDC/レプリケーション設定を保持したリストア

**主要な処理内容**：
1. BackupHistoryオブジェクトの受信と集約
2. 対象データベースの既存プロセス停止/削除
3. SMO Restoreオブジェクトの構築
4. リストア実行またはスクリプト出力
5. 実行結果のPSCustomObject構築と出力

**関連システム・外部連携**：
- Get-DbaBackupInformation / Select-DbaBackupInformation / Format-DbaBackupInformation / Test-DbaBackupInformation
- Azure Blob Storage / S3互換ストレージ（StorageCredential経由）

**権限による制御**：対象データベースへのリストア権限、既存DBの停止・削除権限が必要です。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 該当する画面マッピングなし |

## 機能種別

データ更新処理 / リストア実行

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| BackupHistory | Object[] | Yes | 処理済みBackupHistoryオブジェクト | パイプライン入力対応 |
| SqlInstance | DbaInstanceParameter | No | リストア先インスタンス | - |
| SqlCredential | PSCredential | No | 接続資格情報 | - |
| OutputScriptOnly | switch | No | T-SQLスクリプト出力のみ | - |
| VerifyOnly | switch | No | RESTORE VERIFYONLYのみ実行 | - |
| RestoreTime | datetime | No | ポイントインタイム復旧時刻 | デフォルト: 2日後 |
| StandbyDirectory | string | No | スタンバイファイル格納ディレクトリ | - |
| NoRecovery | switch | No | RESTORING状態で終了 | - |
| MaxTransferSize | int | No | 最大転送サイズ（バイト） | 64KBの倍数 |
| BlockSize | int | No | ブロックサイズ | 512-65536 |
| BufferCount | int | No | I/Oバッファ数 | - |
| Continue | switch | No | 既存リストアシーケンス継続 | - |
| StorageCredential | string | No | Azure/S3ストレージ資格情報 | 別名: AzureCredential, S3Credential |
| WithReplace | switch | No | 既存DB上書き | - |
| KeepReplication | switch | No | レプリケーション設定保持 | - |
| KeepCDC | switch | No | CDC設定保持 | NoRecovery/Standbyと排他 |
| PageRestore | object[] | No | ページレベルリストア対象 | FileId, PageID必須 |
| ExecuteAs | string | No | 実行ログイン名 | - |
| StopMark | string | No | 停止マーク名 | - |
| StopBefore | switch | No | マーク前で停止 | StopMarkと併用 |
| StopAfterDate | datetime | No | マーク検索開始日時 | - |
| Checksum | switch | No | チェックサム検証 | - |
| Restart | switch | No | 中断リストア再開 | - |
| EnableException | switch | No | 例外処理を有効化 | - |

### 入力データソース

- BackupHistoryオブジェクト（パイプライン入力）
- Azure Blob Storage / S3ストレージ（オプション）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverホスト名 |
| InstanceName | string | インスタンス名 |
| SqlInstance | string | 完全インスタンス名 |
| Database | string | リストア先データベース名 |
| DatabaseName | string | データベース名（別名） |
| Owner | string | データベース所有者 |
| DatabaseOwner | string | 所有者（別名） |
| NoRecovery | bool | RESTORING状態か |
| WithReplace | bool | REPLACE使用か |
| KeepReplication | bool | レプリケーション保持 |
| RestoreComplete | bool | リストア完了か |
| BackupFilesCount | int | バックアップファイル数 |
| RestoredFilesCount | int | リストアファイル数 |
| BackupSizeMB | double | バックアップサイズ（MB） |
| CompressedBackupSizeMB | double | 圧縮サイズ（MB） |
| BackupFile | string | バックアップファイルパス（カンマ区切り） |
| RestoredFile | string | リストアファイル名（カンマ区切り） |
| RestoredFileFull | string | リストアファイルフルパス |
| RestoreDirectory | string | リストアディレクトリ |
| BackupSize | dbasize | バックアップサイズ |
| CompressedBackupSize | dbasize | 圧縮サイズ |
| BackupStartTime | datetime | バックアップ開始時刻 |
| BackupEndTime | datetime | バックアップ終了時刻 |
| RestoreTargetTime | object | リストア目標時刻 |
| Script | string | 実行T-SQLスクリプト |
| BackupFileRaw | array | バックアップファイル配列 |
| FileRestoreTime | TimeSpan | ファイルリストア時間 |
| DatabaseRestoreTime | TimeSpan | DBリストア時間 |
| ExitError | Exception | エラー情報 |

### 出力先

- PowerShellパイプライン（PSCustomObject）
- OutputScriptOnly時はT-SQLスクリプト文字列
- VerifyOnly時は検証結果文字列

## 処理フロー

### 処理シーケンス

```
1. begin ブロック
   └─ Connect-DbaInstance
   └─ KeepCDC + NoRecovery/Standby排他チェック
   └─ PageRestore処理準備

2. process ブロック
   └─ BackupHistoryを$internalHistoryに集約

3. end ブロック（各データベースに対して）
   └─ 既存DB処理
      ├─ 通常: Stop-DbaProcess + OFFLINE/ONLINE
      └─ Managed Instance: Remove-DbaDatabase
   └─ バックアップをType/FirstLsnでソート

4. 各バックアップに対して
   └─ SMO Restoreオブジェクト構築
      ├─ NoRecovery/StandbyFile設定
      ├─ StopMark/ToPointInTime設定
      ├─ MaxTransferSize/BlockSize/BufferCount設定
      ├─ RelocateFiles設定
      └─ BackupDeviceItem追加

5. リストア実行分岐
   ├─ KeepCDC: スクリプト + KEEP_CDC
   ├─ PageRestore: スクリプト + PAGE句
   ├─ OutputScriptOnly: Script()のみ
   ├─ VerifyOnly: SqlVerify()
   └─ 通常: SqlRestore() + Progress表示

6. 結果出力
   └─ PSCustomObject構築
   └─ Select-DefaultView
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[begin: Connect-DbaInstance]
    B --> C{KeepCDC + NoRecovery?}
    C -->|Yes| D[Stop-Function エラー]
    C -->|No| E{PageRestore?}
    E -->|Yes| F[ページ情報準備]
    E -->|No| G[process: BackupHistory集約]
    F --> G
    G --> H[end: foreach Database]
    H --> I{DB存在?}
    I -->|Yes| J{Managed Instance?}
    J -->|Yes| K[Remove-DbaDatabase]
    J -->|No| L[Stop-DbaProcess + OFFLINE/ONLINE]
    I -->|No| M[バックアップソート]
    K --> M
    L --> M
    M --> N[foreach Backup]
    N --> O[SMO Restore構築]
    O --> P{実行モード?}
    P -->|KeepCDC| Q[Script + KEEP_CDC]
    P -->|PageRestore| R[Script + PAGE句]
    P -->|OutputScriptOnly| S[Script出力のみ]
    P -->|VerifyOnly| T[SqlVerify実行]
    P -->|通常| U[SqlRestore実行]
    Q --> V[PSCustomObject構築]
    R --> V
    S --> W[スクリプト出力]
    T --> X[検証結果出力]
    U --> V
    V --> Y[Select-DefaultView]
    Y --> Z{次のBackup?}
    Z -->|Yes| N
    Z -->|No| AA{次のDB?}
    AA -->|Yes| H
    AA -->|No| AB[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | KeepCDC排他 | KeepCDCはNoRecovery/Standbyと併用不可 | 常時 |
| BR-02 | Continue効果 | ContinueはWithReplaceを自動有効化 | Continue指定時 |
| BR-03 | 最終バックアップ回復 | 最終バックアップのみNoRecovery=false | デフォルト動作 |
| BR-04 | MI特殊処理 | Managed Instanceは既存DB削除が必要 | MI環境 |
| BR-05 | バックアップソート | Type, FirstLsn順でリストア実行 | 常時 |
| BR-06 | URL検出 | http*/s3*でURLデバイスタイプ使用 | ストレージURL時 |
| BR-07 | ExecuteAs適用 | 最初のバックアップのみEXECUTE AS追加 | ExecuteAs指定時 |

### 計算ロジック

バックアップタイプ変換：
```powershell
$action = switch ($backup.Type) {
    '1' { 'Database' }
    '2' { 'Log' }
    '5' { 'Database' }
    'Transaction Log' { 'Log' }
    Default { 'Database' }
}
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| プロセス停止 | - | ALTER DATABASE | OFFLINE/ONLINE切替 |
| DB削除(MI) | - | DROP DATABASE | 既存DB削除 |
| リストア実行 | - | RESTORE DATABASE/LOG | バックアップリストア |
| 検証実行 | - | RESTORE VERIFYONLY | バックアップ検証 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ConnectionError | インスタンス接続失敗 | 接続情報確認 |
| - | InvalidArgument | KeepCDC + NoRecovery/Standby | パラメータ修正 |
| - | RestoreError | リストア失敗 | バックアップチェーン確認 |

### リトライ仕様

リトライ機能は実装されていません。エラー時はbreakで中断します。

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

SMO Restoreオブジェクトによるリストア操作は、SQL Server側でトランザクション管理されます。

## パフォーマンス要件

- PercentCompleteNotification = 1で1%ごとに進捗表示
- Write-Progressで外部/内部進捗表示
- MaxTransferSize/BufferCount/BlockSizeでI/O最適化可能

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

- StorageCredentialでAzure/S3認証情報を安全に渡す
- ExecuteAsで実行コンテキストを制御可能
- ShouldProcessでWhatIf/Confirm対応

## 備考

- 典型的なパイプラインフロー: Get-DbaBackupInformation | Select-DbaBackupInformation | Format-DbaBackupInformation | Test-DbaBackupInformation | Invoke-DbaAdvancedRestore
- 標準シナリオではRestore-DbaDatabaseを推奨
- SQL Server 2022以上でS3ストレージ対応

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Invoke-DbaAdvancedRestore.ps1 | `public/Invoke-DbaAdvancedRestore.ps1` | パラメータ定義（218-245行目）、多数のリストアオプション |

**読解のコツ**: BackupHistoryがパイプライン必須入力、その他は全てオプション。StorageCredentialの別名（AzureCredential, S3Credential）に注目。

#### Step 2: begin ブロックの初期化を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Invoke-DbaAdvancedRestore.ps1 | `public/Invoke-DbaAdvancedRestore.ps1` | beginブロック（246-268行目）での接続とバリデーション |

**主要処理フロー**:
1. **247-252行目**: Connect-DbaInstance
2. **253-256行目**: KeepCDC排他チェック
3. **258-266行目**: PageRestore準備（FileId:PageID形式）

#### Step 3: end ブロックのリストア処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Invoke-DbaAdvancedRestore.ps1 | `public/Invoke-DbaAdvancedRestore.ps1` | endブロック（274-551行目）でのリストア実行 |

**主要処理フロー**:
- **279-312行目**: 既存DB処理（プロセス停止/MI削除）
- **315-404行目**: SMO Restoreオブジェクト構築
- **406-471行目**: リストア実行分岐（KeepCDC/PageRestore/OutputScriptOnly/VerifyOnly/通常）
- **478-536行目**: 結果PSCustomObject構築

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

```
Invoke-DbaAdvancedRestore
    │
    ├─ begin ブロック
    │      │
    │      ├─ Connect-DbaInstance
    │      │
    │      ├─ KeepCDC排他チェック
    │      │      └─ Stop-Function (エラー時)
    │      │
    │      └─ PageRestore準備
    │             └─ $Pages = FileId:PageID形式
    │
    ├─ process ブロック
    │      └─ $internalHistory += $BackupHistory
    │
    └─ end ブロック (foreach $database)
           │
           ├─ 既存DB処理
           │      ├─ Stop-DbaProcess
           │      ├─ ALTER DATABASE OFFLINE/ONLINE
           │      └─ Remove-DbaDatabase (MI)
           │
           ├─ バックアップソート
           │      └─ Sort-Object Type, FirstLsn
           │
           └─ foreach $backup
                  │
                  ├─ New-Object Microsoft.SqlServer.Management.Smo.Restore
                  │
                  ├─ NoRecovery/StandbyFile設定
                  │
                  ├─ StopMark/ToPointInTime設定
                  │
                  ├─ RelocateFiles追加
                  │      └─ New-Object Smo.RelocateFile
                  │
                  ├─ BackupDeviceItem追加
                  │      └─ URL/Fileデバイスタイプ判定
                  │
                  └─ 実行分岐
                         ├─ KeepCDC: Script() + KEEP_CDC
                         ├─ PageRestore: Script() + PAGE句
                         ├─ OutputScriptOnly: Script()
                         ├─ VerifyOnly: SqlVerify()
                         └─ 通常: SqlRestore()
```

### データフロー図

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

$BackupHistory ──────────▶ process: 集約 ────────────▶ $internalHistory
                                 │
$SqlInstance ────────────▶ Connect-DbaInstance ──────▶ $server
                                 │
$internalHistory ────────▶ Group by Database ────────▶ $databases
                                 │
foreach $database ───────▶ 既存DB処理 ───────────────▶ プロセス停止/削除
                                 │
$database backups ───────▶ Sort Type, FirstLsn ──────▶ $backups
                                 │
foreach $backup ─────────▶ SMO Restore構築 ──────────▶ $restore
    │
    ├─ $backup.FileList ─▶ RelocateFiles ────────────▶ ファイル再配置
    │
    └─ $backup.FullName ─▶ BackupDeviceItem ─────────▶ デバイス設定
                                 │
$restore ────────────────▶ 実行分岐
                                 │
                         ├─ Script() ────────────────▶ T-SQLスクリプト
                         │
                         ├─ SqlVerify() ─────────────▶ "Verify successful/failed"
                         │
                         └─ SqlRestore() ────────────▶ リストア実行
                                 │
結果集約 ────────────────▶ PSCustomObject ───────────▶ Select-DefaultView
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Invoke-DbaAdvancedRestore.ps1 | `public/Invoke-DbaAdvancedRestore.ps1` | ソース | メイン関数実装 |
| Get-DbaBackupInformation.ps1 | `public/Get-DbaBackupInformation.ps1` | ソース | バックアップ情報取得（前段） |
| Select-DbaBackupInformation.ps1 | `public/Select-DbaBackupInformation.ps1` | ソース | バックアップ選択（前段） |
| Format-DbaBackupInformation.ps1 | `public/Format-DbaBackupInformation.ps1` | ソース | バックアップ情報整形（前段） |
| Test-DbaBackupInformation.ps1 | `public/Test-DbaBackupInformation.ps1` | ソース | バックアップ検証（前段） |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続 |
| Stop-DbaProcess.ps1 | `public/Stop-DbaProcess.ps1` | ソース | プロセス停止 |
| Remove-DbaDatabase.ps1 | `public/Remove-DbaDatabase.ps1` | ソース | データベース削除 |
| Select-DefaultView.ps1 | `internal/functions/Select-DefaultView.ps1` | ソース | 出力整形 |
| Get-DbaPathSep.ps1 | `internal/functions/Get-DbaPathSep.ps1` | ソース | パス区切り文字取得 |
