# 機能設計書 165-Invoke-DbaDbClone

## 概要

本ドキュメントは、dbatools PowerShellモジュールの`Invoke-DbaDbClone`コマンドレットに関する機能設計書である。このコマンドは、スキーマと統計情報を含むがテーブルデータを含まない軽量なデータベースクローンを作成する機能を提供する。

### 本機能の処理概要

Invoke-DbaDbCloneは、SQL ServerのDBCC CLONEDATABASEコマンドを使用してスキーマのみのデータベースクローンを作成する。クローンされたデータベースには、すべてのデータベースオブジェクト（テーブル、インデックス、ビュー、プロシージャ）と統計情報が含まれるが、実際のテーブルデータは含まれない。

**業務上の目的・背景**：
パフォーマンストラブルシューティングにおいて、クエリ実行プランとオプティマイザの動作を分析する必要がある場面で、テーブル全体をコピーするストレージオーバーヘッドなしに作業できることが重要。DBAは、テスト環境でのパフォーマンス問題の再現や、サポートケースでベンダーとデータベース構造を共有する際にこの機能を活用する。

**機能の利用シーン**：
- パフォーマンス問題のトラブルシューティング（クエリプラン分析）
- テスト環境でのデータベース構造の再現
- サポートベンダーへのデータベース構造の提供
- スキーマ比較のためのベースライン作成
- 開発環境への構造のみのコピー

**主要な処理内容**：
1. SQL Serverバージョン互換性チェック
2. オプションに応じた統計情報の更新（UpdateStatistics）
3. DBCC CLONEDATABASEの実行
4. クローンデータベースの取得と返却

**関連システム・外部連携**：
- SQL Server Database Engine（DBCC CLONEDATABASE）
- SMO（Server Management Objects）
- Microsoft Tiger Team ツールボックス

**権限による制御**：
- クローン元データベースへのアクセス権限が必要
- データベース作成権限が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLIコマンド | 主機能 | コマンドラインからの直接実行 |

## 機能種別

データベース管理 / スキーマ複製

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | ターゲットのSQL Serverインスタンス | - |
| SqlCredential | PSCredential | No | 代替資格情報 | - |
| Database | string[] | No | クローン元データベース | SqlInstance指定時は必須 |
| InputObject | Database[] | No | Get-DbaDatabaseからのパイプライン入力 | - |
| CloneDatabase | string[] | No | クローン先データベース名（デフォルト: 元DB名_clone） | - |
| ExcludeStatistics | switch | No | 統計情報を除外 | - |
| ExcludeQueryStore | switch | No | Query Storeデータを除外 | - |
| UpdateStatistics | switch | No | クローン前に統計情報を更新 | - |
| WhatIf | switch | No | 実行内容の表示のみ | - |
| Confirm | switch | No | 確認プロンプトの表示 | - |
| EnableException | switch | No | 例外を有効化 | - |

### 入力データソース

- コマンドライン引数
- パイプライン入力（Get-DbaDatabase出力）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverインスタンスのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名（computer\instance） |
| Name | string | クローンされたデータベースの名前 |
| Status | string | 現在のデータベースステータス（Normal、Offline、Recovering等） |
| IsAccessible | boolean | データベースが現在アクセス可能かどうか |
| RecoveryModel | string | データベース復旧モデル（Full、Simple、BulkLogged） |
| LogReuseWaitStatus | string | トランザクションログ再使用のステータス |
| Size | decimal | データベースサイズ（メガバイト） |
| Owner | string | データベース所有者のログイン名 |
| Collation | string | データベース照合順序設定 |
| Encrypted | boolean | 透過的データ暗号化（TDE）が有効かどうか |

### 出力先

コンソール（Microsoft.SqlServer.Management.Smo.Database オブジェクト）

## 処理フロー

### 処理シーケンス

```
1. beginブロック
   ├─ Databaseパラメータ検証（SqlInstance指定時は必須）
   ├─ 統計更新SQLの定義
   └─ バージョン要件の定義
       ├─ SQL 2012 SP4: 11.0.7001
       ├─ SQL 2014 SP2: 12.0.5000
       └─ SQL 2016 SP1: 13.0.4001
2. processブロック
   ├─ InputObjectの取得（SqlInstance指定時はGet-DbaDatabase呼び出し）
   └─ 各データベースのループ処理
       ├─ CloneDatabase名の決定（未指定時は元DB名_clone）
       ├─ バージョン互換性チェック
       ├─ ExcludeStatistics/ExcludeQueryStoreのバージョンチェック
       ├─ システムデータベースチェック
       ├─ UpdateStatistics実行（オプション）
       ├─ DBCC CLONEDATABASE実行
       └─ 結果データベースの取得と返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{SqlInstance指定?}
    B -->|Yes| C{Database指定?}
    C -->|No| D[Stop-Function エラー]
    C -->|Yes| E[Get-DbaDatabase]
    B -->|No| F[パイプラインInputObject使用]

    E --> G[データベースループ開始]
    F --> G

    G --> H{CloneDatabase指定?}
    H -->|No| I[CloneDatabase = 元DB名_clone]
    H -->|Yes| J[指定名を使用]

    I --> K[バージョンチェック]
    J --> K

    K --> L{バージョン互換?}
    L -->|No| M[Stop-Function Continue]
    L -->|Yes| N{ExcludeStatistics/ExcludeQueryStore?}

    M --> G
    N -->|Yes| O[追加バージョンチェック]
    N -->|No| P{システムDB?}

    O --> P
    P -->|Yes| Q[Stop-Function Continue]
    P -->|No| R{UpdateStatistics?}

    Q --> G
    R -->|Yes| S[統計更新SQL実行]
    R -->|No| T[DBCC CLONEDATABASE実行]

    S --> T
    T --> U{クローン先存在?}
    U -->|Yes| V[Stop-Function Continue]
    U -->|No| W[DBCC CLONEDATABASE WITH句構築]

    V --> G
    W --> X[クエリ実行]
    X --> Y[Databases.Refresh]
    Y --> Z[Get-DbaDatabase結果出力]

    Z --> AA{次のCloneDatabase?}
    AA -->|Yes| T
    AA -->|No| BB{次のデータベース?}
    BB -->|Yes| G
    BB -->|No| CC[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | デフォルトクローン名 | CloneDatabase未指定時は「元DB名_clone」 | CloneDatabase未指定 |
| BR-002 | 最小バージョン要件 | SQL 2012 SP4、SQL 2014 SP2、SQL 2016 SP1以上 | 常時 |
| BR-003 | ExcludeStatisticsバージョン | SQL 2014 SP2 CU3以上またはSQL 2016 SP1以上 | ExcludeStatistics=true |
| BR-004 | ExcludeQueryStoreバージョン | SQL 2016 SP1以上 | ExcludeQueryStore=true |
| BR-005 | ユーザーDBのみ | システムデータベースはクローン不可 | 常時 |
| BR-006 | 一意のクローン名 | クローン先データベースは既存であってはならない | 常時 |

### 計算ロジック

**DBCC CLONEDATABASEコマンド構築**:
```sql
DBCC CLONEDATABASE('元DB名','クローン先名') [WITH オプション]
```

**WITH句オプション**:
- NO_STATISTICS: ExcludeStatistics=true時
- NO_QUERYSTORE: ExcludeQueryStore=true時
- 両方指定時: WITH NO_STATISTICS,NO_QUERYSTORE

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 統計更新 | 列ストアインデックス | UPDATE STATISTICS | カラムストア統計の更新 |
| クローン作成 | 新規データベース | CREATE | DBCC CLONEDATABASEによるスキーマクローン |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ParameterError | SqlInstance指定時にDatabase未指定 | Stop-Function |
| - | VersionError | サポートされていないSQL Serverバージョン | Stop-Function -Continue |
| - | SystemDbError | システムデータベースをクローン対象に指定 | Stop-Function -Continue |
| - | ExistsError | クローン先データベースが既に存在 | Stop-Function -Continue |
| - | ExecutionError | DBCC CLONEDATABASE実行失敗 | Stop-Function -Continue |

### リトライ仕様

リトライ機能なし（エラー発生時は次のデータベース/クローン名に継続）

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

該当なし（DBCC CLONEDATABASEは内部でトランザクション管理）

## パフォーマンス要件

- クローン操作は比較的高速（データコピーなし）
- UpdateStatistics実行時は統計更新に時間がかかる可能性あり

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

- クローンされたデータベースにはデータが含まれないため、データ漏洩リスクは低い
- 統計情報からデータ分布が推測可能な場合があることに注意

## 備考

- Microsoft Tiger Teamのコードとアイデアに基づく
- 参考URL:
  - https://sqlperformance.com/2016/08/sql-statistics/expanding-dbcc-clonedatabase
  - https://support.microsoft.com/en-us/help/3177838

---

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

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

### 推奨読解順序

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

バージョン要件とWITH句オプションの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | バージョン定義 | 186-189行目 | sql2012min, sql2014min, sql2014CuMin, sql2016min |
| 1-2 | WITH句構築 | 171-184行目 | noStats, noQueryStore, sqlWith変数 |

**読解のコツ**: バージョン番号は[version]型で比較。SQL 2012=11、SQL 2014=12、SQL 2016=13。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Invoke-DbaDbClone.ps1 | `public/Invoke-DbaDbClone.ps1` | 関数全体の構造とパラメータ定義 |

**主要処理フロー**:
1. **112-124行目**: パラメータ定義
2. **126-190行目**: beginブロック（定義と検証）
3. **191-269行目**: processブロック（メイン処理）

#### Step 3: バージョンチェックロジック

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | バージョンチェック | 206-231行目 | 各バージョンの互換性検証 |

**主要処理フロー**:
- **206-208行目**: SQL 2012 SP4チェック
- **210-212行目**: SQL 2014 SP2チェック
- **214-216行目**: SQL 2016 SP1チェック
- **218-225行目**: ExcludeStatisticsのバージョンチェック
- **227-230行目**: ExcludeQueryStoreのバージョンチェック

#### Step 4: DBCC CLONEDATABASE実行

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | クローン実行 | 250-267行目 | DBCC CLONEDATABASEの構築と実行 |

**主要処理フロー**:
- **252-253行目**: クローン先存在チェック
- **255-259行目**: ShouldProcess確認とクエリ構築
- **260行目**: $db.Invoke($sql)でクエリ実行
- **261行目**: Databases.Refresh()
- **262行目**: Get-DbaDatabase結果出力

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

```
Invoke-DbaDbClone
    │
    ├─ Get-DbaDatabase (SqlInstance指定時)
    │
    ├─ バージョンチェック
    │      └─ $server.VersionMajor, $server.Version比較
    │
    ├─ $db.Invoke($sqlStats) (UpdateStatistics時)
    │      └─ カラムストア統計更新
    │
    ├─ $db.Invoke($sql) (DBCC CLONEDATABASE)
    │
    └─ Get-DbaDatabase (結果取得)
```

### データフロー図

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

SqlInstance ────────────────▶ Get-DbaDatabase ───┐
SqlCredential ─────────────▶                      │
Database ──────────────────▶                      │
        or                                        │
InputObject ───────────────────────────────────▶ データベースループ
                                                   │
                                                   ▼
CloneDatabase ─────────────▶ クローン名決定
                                                   │
                                                   ▼
                              バージョンチェック
                                                   │
                                                   ▼
UpdateStatistics ──────────▶ 統計更新SQL実行（オプション）
                                                   │
                                                   ▼
ExcludeStatistics ─────────▶ WITH句構築
ExcludeQueryStore ─────────▶
                                                   │
                                                   ▼
                              DBCC CLONEDATABASE実行
                                                   │
                                                   ▼
                              ┌────────────────────┐
                              │ Get-DbaDatabase    │──────▶ SMO Database出力
                              │ - クローンDB取得    │
                              └────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Invoke-DbaDbClone.ps1 | `public/Invoke-DbaDbClone.ps1` | ソース | メイン関数定義 |
| Get-DbaDatabase.ps1 | `public/Get-DbaDatabase.ps1` | ソース | データベース取得（入力・出力） |
