# 機能設計書 128-Get-DbaLastGoodCheckDb

## 概要

本ドキュメントは、データベースの最終成功DBCC CHECKDBタイムスタンプと整合性チェック状態を取得するGet-DbaLastGoodCheckDb機能の設計仕様を記載する。

### 本機能の処理概要

Get-DbaLastGoodCheckDbは、各データベースについて最後に成功したDBCC CHECKDB操作のタイムスタンプとデータベース作成日を比較し、整合性チェックのコンプライアンス状況を評価する機能である。

**業務上の目的・背景**：DBCC CHECKDBは、データベースの整合性を検証する重要なメンテナンス操作である。DBAは、各データベースが定期的にチェックされているかを監視し、チェックが遅れているデータベースを特定する必要がある。本機能により、整合性チェックのコンプライアンス監査を効率化できる。

**機能の利用シーン**：
- データベース整合性チェックのコンプライアンス監視
- メンテナンスルーチンの有効性確認
- 注意が必要なデータベースの特定
- 定期監査レポートの作成

**主要な処理内容**：
1. 対象データベースに対してDBCC DBINFO WITH TABLERESULTSを実行（SQL 2008以前）
2. または SMOのLastGoodCheckDbTimeプロパティを使用（SQL 2008 R2以降）
3. 最終CHECKDBからの経過日数を計算
4. データベース作成日と比較してステータスを判定（Ok / New database / CheckDB should be performed）
5. Data Purityの有効状態を確認

**関連システム・外部連携**：SQL Server DBCC コマンド、SMO (Server Management Objects)

**権限による制御**：DBCC DBINFOの実行にはsysadminロールが必要。SQL 2008 R2以降ではdb_ownerでも一部情報取得可能。

## 関連画面

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

## 機能種別

データ取得(SELECT) / 監視・コンプライアンス

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 対象SQL Serverインスタンス | ValueFromPipeline |
| SqlCredential | PSCredential | No | 代替認証情報 | Windows/SQL認証対応 |
| Database | object[] | No | フィルタリング対象データベース名 | ワイルドカード可 |
| ExcludeDatabase | object[] | No | 除外するデータベース名 | ワイルドカード可 |
| InputObject | object[] | No | パイプラインからのデータベースオブジェクト | ValueFromPipeline |
| EnableException | switch | No | 例外を直接スローするか | - |

### 入力データソース

- SQL Serverインスタンス
- DBCC DBINFO結果（SQL 2008以前、またはsysadmin時）
- SMO Database.LastGoodCheckDbTime（SQL 2008 R2以降）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverホストのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全修飾インスタンス名 |
| Database | string | データベース名 |
| DatabaseCreated | datetime | データベース作成日時（取得不可時は$null） |
| LastGoodCheckDb | datetime | 最終成功DBCC CHECKDB日時（未実行時は$null） |
| DaysSinceDbCreated | double | データベース作成からの経過日数 |
| DaysSinceLastGoodCheckDb | int | 最終CHECKDBからの経過日数（未実行時は存在しない） |
| Status | string | ステータス判定（Ok / New database, not checked yet / CheckDB should be performed） |
| DataPurityEnabled | bool | Data Purity有効状態（SQL 2008以降でnon-sysadminの場合は$null） |
| CreateVersion | int | データベース作成時のSQL Serverバージョン |
| DbccFlags | int | DBCC フラグ値 |

### 出力先

- PowerShellパイプライン（PSCustomObject）
- コンソール出力

## 処理フロー

### 処理シーケンス

```
1. SqlInstanceまたはInputObjectを処理
   └─ 入力タイプを判定（DbaInstanceParameter/Server/Database）

2. Get-DbaDatabaseでデータベースオブジェクト取得
   └─ Database/ExcludeDatabase でフィルタリング

3. 各データベースをループ処理
   └─ IsAccessible確認

4. 権限とバージョンに応じた処理分岐
   ├─ SQL 2008以前 or sysadmin: DBCC DBINFO使用
   └─ SQL 2008 R2以降 non-sysadmin: SMOプロパティ使用

5. DBCC DBINFO実行時
   └─ dbi_dbccLastKnownGood, dbi_createVersion, dbi_dbccFlags抽出

6. ステータス判定
   ├─ 7日以内にCHECKDB実行: "Ok"
   ├─ 7日以内に作成: "New database, not checked yet"
   └─ それ以外: "CheckDB should be performed"

7. PSCustomObjectとして出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{入力タイプ判定}
    B -->|SqlInstance| C[Get-DbaDatabase]
    B -->|Database| D[InputObjectを直接使用]
    C --> E{データベースループ}
    D --> E
    E -->|各DB| F{IsAccessible?}
    F -->|No| G[Stop-Function、スキップ]
    F -->|Yes| H{sysadmin or SQL 2008以前?}
    H -->|Yes| I[DBCC DBINFO実行]
    H -->|No| J[SMO LastGoodCheckDbTime使用]
    I --> K[dbi_dbccLastKnownGood抽出]
    J --> L[LastGoodCheckDbTime取得]
    K --> M[経過日数計算]
    L --> M
    M --> N{ステータス判定}
    N -->|7日以内CHECKDB| O[Status = Ok]
    N -->|7日以内作成| P[Status = New database]
    N -->|それ以外| Q[Status = CheckDB should be performed]
    O --> R[PSCustomObject出力]
    P --> R
    Q --> R
    R --> E
    G --> E
    E -->|全DB完了| S[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | ステータス判定: Ok | 7日以内にDBCC CHECKDBが実行済み | daysSinceCheckDb < 7 |
| BR-002 | ステータス判定: New | 7日以内に作成され、CHECKDBが未実行 | daysSinceDbCreated < 7 |
| BR-003 | ステータス判定: Should perform | 7日以上CHECKDBが未実行 | それ以外 |
| BR-004 | Data Purity判定 | createVersion < 611 かつ dbccFlags = 0 の場合は無効 | SQL 2005以降のアップグレードDB |
| BR-005 | 複数dbi_dbccLastKnownGood | SQL 2008 R2のバグで複数フィールドがある場合、最新値を使用 | SQL 2008 R2環境 |

### 計算ロジック

- **DaysSinceDbCreated**: `(New-TimeSpan -Start $datecreated -End (Get-Date)).TotalDays`
- **DaysSinceLastGoodCheckDb**: `(New-TimeSpan -Start $lastKnownGood -End (Get-Date)).Days`

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| CHECKDB情報取得 | DBCC DBINFO | DBCC | データベース内部情報取得 |
| sysadmin判定 | - | SELECT | IS_SRVROLEMEMBER('sysadmin') |

### DBCC コマンド詳細

#### DBCC DBINFO

| 操作 | 項目（Field名） | 取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| 読み取り | dbi_dbccLastKnownGood | WITH TABLERESULTS | 最終CHECKDB成功日時 |
| 読み取り | dbi_createVersion | WITH TABLERESULTS | 作成時バージョン |
| 読み取り | dbi_dbccFlags | WITH TABLERESULTS | DBCCフラグ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | アクセス不可 | データベースがIsAccessible=false | Stop-Function -Continueでスキップ |
| - | 入力エラー | SqlInstanceもInputObjectも未指定 | Warning出力してreturn |

### リトライ仕様

リトライ処理なし。エラー発生時はスキップして次のデータベースを処理。

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

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

## パフォーマンス要件

- DBCC DBINFOは軽量だが、全データベースで実行すると若干時間がかかる
- SQL 2008 R2以降でnon-sysadminの場合はSMOプロパティで高速取得

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

- DBCC DBINFOの実行にはsysadminロールが推奨
- Azure SQL Databaseではsysadmin判定がfalseになる
- SqlCredentialによる認証情報の安全な受け渡し

## 備考

- DBCC DBINFOは非公開機能（undocumented）
- DBCC CHECKFILEGROUPやDBCC CHECKDB WITH PHYSICAL_ONLYでもLastKnownGoodが更新される
- READ_ONLYデータベースではLastKnownGoodが更新されない
- 参考:
  - https://msdn.microsoft.com/en-us/library/ms176064.aspx
  - http://www.sqlskills.com/blogs/paul/checkdb-from-every-angle-how-to-tell-if-data-purity-checks-will-be-run/

---

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

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

### 推奨読解順序

#### Step 1: 入力タイプ判定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaLastGoodCheckDb.ps1 | `public/Get-DbaLastGoodCheckDb.ps1` | processブロックの入力分岐 |

**主要処理フロー**:
1. **128-132行目**: Test-Boundで必須入力チェック
2. **138-157行目**: 入力タイプ判定（DbaInstanceParameter/Server/Database）
3. **143-147行目**: Get-DbaDatabaseでフィルタリング

**読解のコツ**:
- `$input.GetType().FullName`でswitchしている
- InputObjectは複数の型を受け入れる（DbaInstanceParameter、SMO Server、SMO Database）

#### Step 2: DBCC DBINFO処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaLastGoodCheckDb.ps1 | `public/Get-DbaLastGoodCheckDb.ps1` | DBCC DBINFO実行とパース |

**主要処理フロー**:
- **169-173行目**: IS_SRVROLEMEMBER('sysadmin')でsysadmin判定
- **175-196行目**: DBCC DBINFO実行とフィールド抽出
- **181-187行目**: 複数dbi_dbccLastKnownGoodの処理（SQL 2008 R2バグ対応）
- **192-196行目**: Data Purity判定ロジック
- **197-200行目**: SQL 2008 R2以降でnon-sysadminはSMOプロパティ使用

#### Step 3: ステータス判定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaLastGoodCheckDb.ps1 | `public/Get-DbaLastGoodCheckDb.ps1` | Status判定ロジック |

**主要処理フロー**:
- **211-212行目**: 経過日数計算
- **214-220行目**: ステータス判定（Ok / New database / Should be performed）
- **222-228行目**: 無効日時の除去（1/1/1900）

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

```
Get-DbaLastGoodCheckDb
    │
    ├─ Test-Bound (入力チェック)
    │
    ├─ Get-DbaDatabase (SqlInstance指定時)
    │      └─ Database/ExcludeDatabaseフィルタ
    │
    ├─ IS_SRVROLEMEMBER (権限チェック)
    │
    ├─ DBCC DBINFO (sysadmin or SQL 2008以前)
    │      └─ dbi_dbccLastKnownGood抽出
    │
    └─ SMO LastGoodCheckDbTime (SQL 2008 R2以降)
```

### データフロー図

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

SqlInstance    ───▶  Get-DbaDatabase          ───▶
  or                       │
InputObject                │
                     IS_SRVROLEMEMBER          ───▶
                           │
           ┌───────────────┼───────────────┐
           │               │               │
    [sysadmin/SQL2008以前]  │  [SQL2008R2以降non-admin]
           │               │               │
    DBCC DBINFO    ───▶   └───────────────▶   SMO LastGoodCheckDbTime
           │                               │
     dbi_dbccLastKnownGood                 │
           │                               │
           └───────────────┬───────────────┘
                           │
                     経過日数計算          ───▶
                           │
                     ステータス判定        ───▶  PSCustomObject出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaLastGoodCheckDb.ps1 | `public/Get-DbaLastGoodCheckDb.ps1` | ソース | メイン関数定義 |
| Get-DbaLastGoodCheckDb.Tests.ps1 | `tests/Get-DbaLastGoodCheckDb.Tests.ps1` | テスト | 単体・統合テスト |
| Get-DbaDatabase.ps1 | `public/Get-DbaDatabase.ps1` | ソース | データベースオブジェクト取得 |
