19
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AIエージェントと MCPサーバーで Oracle AWR レポートを生成・分析してみよう

19
Last updated at Posted at 2026-01-05

このブログは?

Gemini_Generated_Image_u47uwju47uwju47u.png

OSS の コーディングAIエージェント Cline と Oracle データベースへの接続ツールの Oracle SCLcl MCP Server そして、AIモデルには、OCI Generative AI Service(OCI 生成AIサービス)の xai.grok-4-fast-reasoning モデルを使って Autonomous AI Database の AWR レポートを生成、分析してみましたので、そのご紹介です。コーディングAIエージェントの力を借りて作業するだけではなく、エージェントの力を借りて確立した手順をワークフロー化して再現性よく効率的なDBA作業を目指してみました。

Cline とは?

Cline は、VS Code の拡張機能として動作する AI 駆動開発アシスタントです。Claude、GPT-4、その他のAIモデルを活用して、コーディング、デバッグ、ドキュメント作成などの開発タスクを自動化・支援してくれるものです。

Cline の特徴

  • 多様なAI Providerの多様なAIモデルに対応している
  • Planモード とタスクを実行する Actモード がある
    • Planモードは、タスク実行の計画を対話的に立案するモードです。
    • Actモード は、Planモードで立てた計画に基づいて実際にタスクを実行するモードです。
    • タスクを実行する前にAIエージェントが何をしようとしているのかを確認しておきたいことがあります。しかし、Planモードを持たないコーディングエージェントは、ユーザーが明示的に「まだ実装はしないでください。計画立案だけを行ってください」などと指示しないと計画立案に続いて自動的に実装まで進んでしまったりします。しかし、Clineでは、Planモードでは確実に計画の立案とレビューだけを行い、実行は Actモードに切り替えて行うということを明確に分けることができます。最近、他のコーディングエージェントにも広がりつつある機能です
  • ワークフローを定義できる
    • 定型的なタスクを定められた手順で実行するワークフローを定義することができます。

Oracle SQLcl MCP Server とは?

Oracle Database のコマンドラインインターフェース (CLI) の Oracle SQLcl が MCPサーバーとして動作するようになりました。SQLcl は、sql コマンドに -mcp オプションを付けて起動すると STDIO トランスポートで MCP クライアントと通信する MCP サーバーになり、データベース操作をツールとしてAIエージェントから利用できるようになります。

image.png

システム構成

今回は、AIモデルには、OCI Generative AI Service(OCI 生成AIサービス)の xai.grok-4-fast-reasoning モデルを使用しています。

image.png

シーケンス図

環境構築

Cline と OCI Generative AI サービスの統合環境の構築詳細については、別の記事を書いていますので試してみたい方は参考にしてみてください。

上記記事では、AIモデルは、xai.grok-4 を例にしていますが、今回は、OCI Generative AI サービスで利用できる xAI のより新しいモデルの xai.grok-4-fast-reasoning を使っています。xai.grok-4 よりも性能が向上して、速度も速くなったモデルです。

OCI のコンピュートインスタンス上に環境をつくる手順も下記に公開しています。

エージェントのルール

Cline には、AIエージェントである Cline が従うべきルールを定義することができます。システムレベルで適用される Global Rules と VS Code の Workspace 単位で適用される Workspace Rules の2種類があります。
今回は、MCPサーバーの利用、Oracle Database へのクエリー発行、AWRレポートの生成に関する注意事項を Global Rules に記載しました。

AIモデルは、事前学習で Oracle Database についてかなりの知識を得ていますので、このようなルールを記載しなくても Oracle Database を操作できますが、間違えること(ディクショナリのカラム名を間違えるなど)も少なくありませんので、よくある間違いについてこのようなガイドを定義しておくとスムースですのでお勧めです。

エージェントのルールを定義する

Global Rules を設定するには以下の手順を踏みます

  • 画面下部の 「@」、「+」、ハンバーガーメニューのとなりにある天秤ばかりのボタンをクリック

image.png

  • 「Rules」タブを選択
  • Global Rules 直下にルールの名前を入力
  • 右の「+」をクリック
  • エディターが開くのでルールを入力
  • エディターを閉じる
  • 右端にあるスライダースイッチが青くなっていることを確認

image.png

Cline Global Rules の詳細
# Cline Rules for Oracle AWR

## [CRITICAL] ORA-00904 (invalid identifier) 発生時の強制プロトコル

このセクションは全ルールより優先される。違反は許容されない。

### 強制フロー
```
[TRIGGER] ORA-00904 または "invalid identifier" エラーが発生
    |
    v
[STOP] 次のクエリ実行を禁止。修正したSQLをすぐに実行してはならない。
    |
    v
[REQUIRED] DESCRIBE <エラーが発生したテーブル/ビュー> を実行
    |
    v
[REQUIRED] カラム一覧を確認し、存在するカラムのみでSQLを再構築
    |
    v
[REQUIRED] 修正理由を説明してから、修正したSQLを実行
```

### 禁止行動

以下の行動は絶対に禁止する:

- DESCRIBEを実行せずにカラム名を変更・削除して再試行すること
- 「おそらくこのカラム名だろう」という推測での修正
- エラーメッセージだけを見て修正を試みること
- DESCRIBEの結果を確認せずに次のクエリを発行すること

### 必須行動

以下の行動は必ず実行する:

- DESCRIBE または `SELECT column_name FROM all_tab_columns WHERE table_name = '...'` を実行してカラム一覧を取得
- 取得したカラム一覧と照合してからSQLを修正
- 確認結果を応答に含める(例:「DESCRIBEの結果、SNAP_IDカラムは存在しませんでした。利用可能なカラムは...」)

### 具体例

[FORBIDDEN] 誤った対応:
```
1. SELECT SNAP_ID, OBJECT_NAME FROM DBA_HIST_SQL_PLAN ... 
   → エラー: ORA-00904: SNAP_ID: invalid identifier
2. [DESCRIBEを実行しない] ← ルール違反
3. SELECT OBJECT_NAME FROM DBA_HIST_SQL_PLAN ... を再試行
```

[CORRECT] 正しい対応:
```
1. SELECT SNAP_ID, OBJECT_NAME FROM DBA_HIST_SQL_PLAN ... 
   → エラー: ORA-00904: SNAP_ID: invalid identifier
2. DESCRIBE DBA_HIST_SQL_PLAN を実行 ← 必須ステップ
3. [結果を確認: SNAP_IDは存在しない。存在するカラム: DBID, SQL_ID, PLAN_HASH_VALUE, ID, OPERATION, ...]
4. ユーザーに報告:「DESCRIBEの結果、SNAP_IDカラムは存在しません。利用可能なカラムは...」
5. 存在するカラムのみを使用して修正したSQLを実行
```

---

## [CRITICAL] Actモードでのツール実行

- Actモードでは必ず1つ以上のツールを呼び出す(例外なし)
- 質問・確認が必要な場合: `ask_followup_question` ツールを使用
- 作業完了時: `attempt_completion` を呼び出す
- 確認だけの応答(ツールを使わない応答)は禁止

---

## [CRITICAL] SQLエラー発生後の共通ルール

### 禁止事項

- 同じクエリを繰り返し実行すること
- 原因を特定せずに単純にSQLを書き換えること
- メタデータを確認せずに修正を試みること

### 必須事項

- エラー発生後は、まずメタデータを確認する(DESCRIBE、データディクショナリ参照)
- エラーメッセージから根本原因を特定してから次のアクションを決定する
- 3回同じエラーが発生したら、アプローチを根本的に変更する

### エラー種別ごとの対処

ORA-00904 (invalid identifier):
→ 上記の「強制プロトコル」に従う

ORA-00942 (table or view does not exist):
→ `SELECT table_name FROM user_tables WHERE table_name LIKE '%キーワード%'` でテーブル存在確認
→ `SELECT owner, table_name FROM all_tables WHERE table_name = '...'` でスキーマ所有者を確認
→ ユーザーに報告

---

## 進捗管理

- `task_progress` を使って、常に「現在何をしていて、次に何をするか」を明示
- 長時間タスクの場合: 定期的にTODOリストを更新し、進捗を記録

---

## ユーザーとのコミュニケーション

### 不明点の確認

- タスクの目的や環境設定が不明確な場合は、推測で進めず `ask_followup_question` を使用してユーザーに確認
- タスクが空または不明確な場合は、まず確認する

### エラー報告

エラーが発生した場合は、`ask_followup_question` を使用してユーザーにエラーの状況と対策案を提示:
- エラーの種類(ORA-XXXXX, MCPエラーなど)
- 発生した状況(どのツール、どのSQL)
- 次に試みる対策

### タスクが中断された場合の再開

ユーザーへの質問ではなくツールで環境を確認:
- データベースの接続状態、利用可能なデータベース接続
- TODOリスト(進捗確認)

---

## URLの提示をしない

URLを参考リンクとして出力しない。

---

## MCPツール実行の基本原則

### 基本方針

- すべてのデータベースクエリはMCPツールを通じて実行する
- MCPツールのレスポンスは、正常に返された場合のみ事実として扱う
- 事前知識やコンテキストに基づいて、出力を推測、仮定、捏造してはならない
- MCPツールのレスポンスが空の場合も出力を推測、仮定、捏造してはならない

### MCPサーバーの正確な利用

- MCPサーバーの名称は必ず正確なサーバー名を使用する
- 推測や略称は絶対に使わない
- 初回接続時は必ずサーバー名を確認してからtoolを呼び出す

[FORBIDDEN] サーバー名の省略:
- 本当のサーバー名が `SQLcl - SQL Developer` であるとき、`SQLcl` と省略することは禁止

### SQLcl MCPサーバーのルール

- クエリ実行には `run-sql` よりも `run-sqlcl` を優先する
- 純粋なSQL実行が必要な場合のみ `run-sql` を使用する

[FORBIDDEN] 以下のコマンドはMCPツールでエラーとなる:
- SET PAGESIZE
- SET LINESIZE
- SET COLSEP
- SET SQLFORMAT
- SPOOL

### ツール実行が失敗、タイムアウト、またはデータが返されない場合

- 結果が取得できなかったことをユーザーに明示的に伝える
- 結果を補完、推定、推測しようとしてはならない
- 再試行するか、クエリを修正するか、追加情報を提供するかをユーザーに確認する
- ツールの結果が部分的な場合は、ユーザーに確認されるまで信頼性がないものとして扱う

### JSONパラメータのフォーマット

- パラメータは必ず有効なJSON形式で記述
- 特殊文字(`\n`, `"`, `'` など)は適切にエスケープ
- 複雑なSQLを渡す場合は、JSON文字列として適切にエンコード
- JSON形式の後に通常のテキストやXMLタグなどを出力しない

---

## データベースクエリのワークフロー

### 接続とセッションの管理

1. 利用可能な接続のリストの事前確認: データベース操作を伴うタスクでは、まずツールで利用可能な接続を確認
2. 使用する接続をユーザーに確認: 接続のリストを `ask_followup_question` ツールのオプションとしてユーザーに提示
3. 接続確立: ツールで接続を確立
4. 接続エラー後の対応: `Connection closed` などのエラーが発生した場合は、利用可能な接続のリストをツールで再確認してから再接続

### メタデータの事前確認

ORA-00942やORA-00904エラーを回避するため、クエリを実行する前に以下を確認する:

テーブルやビューの一覧の取得:
- データベースオブジェクトのリストを取得するツールがあれば使用
- 無い場合は `SELECT table_name FROM user_tables` などを実行

[REQUIRED] テーブルやビューの構造の確認:
- データベースオブジェクトの詳細を取得するツールがあれば使用
- 無い場合は `DESCRIBE table_name` を実行、または `SELECT * FROM all_tab_columns WHERE table_name = 'TABLE_NAME'` を実行
- スキーマの所有者の確認

### 3ステップ実行ルール

すべてのSQLクエリリクエストはこのワークフローに従う。いかなるステップもスキップしてはならない。

| ステップ | アクション | 目的 |
|----------|------------|------|
| 1 | DESCRIBE | スキーマ確認 |
| 2 | SELECT COUNT(*) | 行数の検証 |
| 3 | 実際のクエリ | ユーザーの元のリクエストを実行 |

[WARNING] ステップ3は必須。DESCRIBEとSELECT COUNT(*)は準備ステップに過ぎず、実際のクエリの代わりにはならない。

#### ステップ1: スキーマ確認(DESCRIBE)

- 現在のセッションで初めて登場するテーブル名、ビュー名については、まず `DESCRIBE` を実行してテーブルやビューの構造を確認
- カラム定義を確認してから、実際のSQLクエリを構築
- 自然言語だけでカラム名やデータ型を仮定してはならない
- `DESCRIBE` が失敗した場合やテーブルが存在しない場合は、推測せずにユーザーに確認

#### ステップ2: 行数の検証(COUNT)

- 実際のクエリと同じテーブル、ビュー、WHERE句を使用した `SELECT COUNT(*)` クエリを実行
- 行数が1000行を超える場合: ユーザーに通知し、フィルター追加や制限を提案、承認を待つ

#### ステップ3: 実際のクエリを実行

[REQUIRED] ステップ1と2を完了した後、ユーザーがリクエストした元のSQLクエリを必ず実行する。
[REQUIRED] SQLがステップ1で確認したテーブル構造、カラム名、データ型に基づいていることを確認する。
- このステップの実際のツール出力のみに基づいて結果を報告する

### 100行を超える結果セットの処理

- データ全体をそのまま出力することは避ける
- 要約を提供する: 集計統計、上位Nレコード、またはサマリーテーブル

### タイムゾーンに関する注意事項

- テーブルやビューのタイムスタンプ型のカラムにタイムゾーンを保持した型(TIMESTAMP WITH TIME ZONE)がある場合には、それを使用する
- カラムにタイムゾーンを保持した型(TIMESTAMP WITH TIME ZONE)がない場合は、カラムデータはデータベースタイムゾーンで保存されているものとして、セッションタイムゾーンに正しく変換する

---

## Oracleデータディクショナリの使用

- どのデータディクショナリビューが利用可能かを推測してはならない
- まず `DICTIONARY` ビューをクエリする:
```sql
SELECT table_name, comments FROM DICTIONARY ORDER BY table_name;
```
- 実際にアクセス可能なビューのみを選択する
- ディクショナリビューについても3ステップワークフローに従う
- 必要なビューがDICTIONARYに表示されない場合は、ユーザーにその制限を説明する

---

## PL/SQLパッケージ・プロシージャ呼び出しのルール

PL/SQLパッケージのプロシージャ/ファンクションを呼び出す前に、必ずシグネチャを確認する。

### シグネチャ確認方法
```sql
SELECT argument_name, position, data_type, defaulted, in_out
FROM all_arguments
WHERE package_name = 'PACKAGE_NAME'
  AND object_name = 'PROCEDURE_NAME'
ORDER BY position;
```

### 禁止事項

- パラメータの推測: 事前知識やドキュメントの記憶に基づいてパラメータを推測してはならない
- 存在確認なしの呼び出し: シグネチャを確認せずにPL/SQLプロシージャを実行してはならない
- 「便利そうな」パラメータの追加: データディクショナリで確認できたパラメータのみを使用する

### 正しいフロー例
```
ユーザー: "ジョブを停止して"
1. 実行: DBMS_SCHEDULER について ALL_ARGUMENTS をクエリ
2. 確認: STOP_JOB のパラメータは job_name, force, commit_semantics のみ
3. 実行: BEGIN DBMS_SCHEDULER.STOP_JOB('JOB_NAME', force => TRUE); END;
```

### 誤ったフロー例
```
ユーザー: "ジョブを停止して"
1. スキップ: シグネチャ確認なし ← ルール違反
2. 実行: BEGIN DBMS_SCHEDULER.STOP_JOB('JOB_NAME', force => TRUE, timeout => 300); END;
   ↑ timeout は存在しないパラメータ(PLS-00306 エラー)
```

---

## [CRITICAL] CDB/PDB環境でのAWR関連ビュー選択ルール

このルールは、AWRレポート生成だけでなく、AWR関連データを直接クエリするすべての場面に適用される。

### 適用範囲

以下のいずれかに該当する場合、このルールを適用する:
- AWRレポートを生成する場合
- AWR関連のパフォーマンス統計を取得する場合(例:バッファキャッシュヒット率、I/O統計、待機イベントなど)
- DBA_HIST_* または AWR_PDB_* ビューを使用する場合

### CDB/PDB環境の判定(必須)

[REQUIRED] AWR関連のビューを使用する前に、必ず以下のクエリで環境を判定する:
```sql
SELECT 
    SYS_CONTEXT('USERENV', 'CON_NAME') AS CONTAINER_NAME,
    SYS_CONTEXT('USERENV', 'CON_ID') AS CONTAINER_ID,
    CASE 
        WHEN SYS_CONTEXT('USERENV', 'CON_ID') = 1 THEN 'CDB$ROOT'
        WHEN SYS_CONTEXT('USERENV', 'CON_ID') = 0 THEN 'Non-CDB'
        ELSE 'PDB'
    END AS ENVIRONMENT_TYPE
FROM DUAL;
```

### ビュー選択マッピング

| 環境タイプ | スナップショットビュー | 統計ビュー | SQLSTATビュー | 他のAWRビュー |
|------------|------------------------|------------|---------------|---------------|
| Non-CDB (CON_ID=0) | DBA_HIST_SNAPSHOT | DBA_HIST_SYSSTAT | DBA_HIST_SQLSTAT | DBA_HIST_* |
| CDB$ROOT (CON_ID=1) | DBA_HIST_SNAPSHOT | DBA_HIST_SYSSTAT | DBA_HIST_SQLSTAT | DBA_HIST_* |
| PDB (CON_ID>=2) | AWR_PDB_SNAPSHOT | AWR_PDB_SYSSTAT | AWR_PDB_SQLSTAT | AWR_PDB_* |

### 強制ルール

[REQUIRED] PDB環境(CON_ID >= 2)では、以下のビューマッピングを必ず適用する:

| CDB/Non-CDBビュー | PDB環境での対応ビュー |
|-------------------|----------------------|
| DBA_HIST_SNAPSHOT | AWR_PDB_SNAPSHOT |
| DBA_HIST_SYSSTAT | AWR_PDB_SYSSTAT |
| DBA_HIST_SQLSTAT | AWR_PDB_SQLSTAT |
| DBA_HIST_SQLTEXT | AWR_PDB_SQLTEXT |
| DBA_HIST_SQL_PLAN | AWR_PDB_SQL_PLAN |
| DBA_HIST_ACTIVE_SESS_HISTORY | AWR_PDB_ACTIVE_SESS_HISTORY |
| DBA_HIST_SYSTEM_EVENT | AWR_PDB_SYSTEM_EVENT |
| DBA_HIST_SYS_TIME_MODEL | AWR_PDB_SYS_TIME_MODEL |

[FORBIDDEN] PDB環境で DBA_HIST_* ビューを使用すること(CDBレベルのデータが返されるため不正確)

### 検証フロー
```
[TRIGGER] AWR関連のクエリ実行リクエスト
    |
    v
[STEP 1] CDB/PDB環境を判定(SYS_CONTEXTで確認)
    |
    v
[STEP 2] 環境に応じたビューを選択
    |
    +---> CON_ID = 0 または CON_ID = 1
    |         |
    |         v
    |     DBA_HIST_* ビューを使用
    |
    +---> CON_ID >= 2 (PDB)
              |
              v
          [REQUIRED] AWR_PDB_* ビューを使用
          [FORBIDDEN] DBA_HIST_* ビューの使用
    |
    v
[STEP 3] 選択したビューでDESCRIBEを実行(3ステップ実行ルールに従う)
    |
    v
[STEP 4] クエリを実行
```

### 正しい例と誤った例

#### 例1: バッファキャッシュヒット率の計算

[FORBIDDEN] PDB環境での誤った対応:
```sql
-- 環境判定: CON_ID = 747 (PDB)
-- 誤り: DBA_HIST_SYSSTATを使用
SELECT STAT_NAME, VALUE 
FROM DBA_HIST_SYSSTAT 
WHERE STAT_NAME IN ('db block gets', 'consistent gets', 'physical reads');
```

[CORRECT] PDB環境での正しい対応:
```sql
-- 環境判定: CON_ID = 747 (PDB)
-- 正しい: AWR_PDB_SYSSTATを使用
SELECT STAT_NAME, VALUE 
FROM AWR_PDB_SYSSTAT 
WHERE STAT_NAME IN ('db block gets', 'consistent gets', 'physical reads');
```

#### 例2: SQL実行統計の取得

[FORBIDDEN] PDB環境での誤った対応:
```sql
-- 環境判定: CON_ID = 747 (PDB)
SELECT SQL_ID, EXECUTIONS, ELAPSED_TIME 
FROM DBA_HIST_SQLSTAT;  -- 誤り
```

[CORRECT] PDB環境での正しい対応:
```sql
-- 環境判定: CON_ID = 747 (PDB)
SELECT SQL_ID, EXECUTIONS, ELAPSED_TIME 
FROM AWR_PDB_SQLSTAT;  -- 正しい
```

### 一貫性チェック

[REQUIRED] 計画策定時と実行時のビュー選択が一貫していることを確認する:
- 計画で「AWR_PDB_SNAPSHOT」を使用すると決定した場合、統計ビューも「AWR_PDB_SYSSTAT」を使用すること
- 計画で「DBA_HIST_SNAPSHOT」と「AWR_PDB_SYSSTAT」を混在させることは禁止

---

## AWRレポート関数(DBMS_WORKLOAD_REPOSITORY)使用時のルール

注意: AWR関連ビューを直接クエリする場合は「CDB/PDB環境でのAWR関連ビュー選択ルール」セクションを参照すること。

### CDB/PDB環境の判定

[REQUIRED] AWRレポートを生成する前に、まず現在の接続環境がCDBかPDBかを確認する:
```sql
SELECT 
    SYS_CONTEXT('USERENV', 'CON_NAME') AS CONTAINER_NAME,
    SYS_CONTEXT('USERENV', 'CON_ID') AS CONTAINER_ID,
    CASE 
        WHEN SYS_CONTEXT('USERENV', 'CON_ID') = 1 THEN 'CDB$ROOT'
        WHEN SYS_CONTEXT('USERENV', 'CON_ID') = 0 THEN 'Non-CDB'
        ELSE 'PDB'
    END AS ENVIRONMENT_TYPE
FROM DUAL;
```

### 環境に応じたDBIDとスナップショットの確認

#### CDB$ROOT または Non-CDB の場合

CDB$ROOTまたはNon-CDB環境では、`DBA_HIST_SNAPSHOT` と `GV$INSTANCE` を使用する:
```sql
SELECT 
    S.DBID, 
    I.INSTANCE_NUMBER, 
    S.SNAP_ID, 
    S.BEGIN_INTERVAL_TIME, 
    S.END_INTERVAL_TIME
FROM 
    DBA_HIST_SNAPSHOT S, 
    GV$INSTANCE I 
WHERE 
    S.INSTANCE_NUMBER = I.INSTANCE_NUMBER 
    AND S.END_INTERVAL_TIME >= SYSTIMESTAMP - INTERVAL '24' HOUR
    AND S.END_INTERVAL_TIME < SYSTIMESTAMP
ORDER BY 
    S.SNAP_ID;
```

#### PDB の場合

[FORBIDDEN] PDB環境では `V$DATABASE` からDBIDを取得すること(CDBのDBIDが返されるため)

[REQUIRED] PDB環境では、`AWR_PDB_SNAPSHOT` と `GV$INSTANCE` をジョインして確認する:
```sql
SELECT 
    A.DBID, 
    I.INSTANCE_NUMBER, 
    A.SNAP_ID, 
    A.BEGIN_INTERVAL_TIME_TZ, 
    A.END_INTERVAL_TIME_TZ
FROM 
    AWR_PDB_SNAPSHOT A, 
    GV$INSTANCE I 
WHERE 
    A.INSTANCE_NUMBER = I.INSTANCE_NUMBER 
    AND A.END_INTERVAL_TIME_TZ >= SYSTIMESTAMP - INTERVAL '24' HOUR
    AND A.END_INTERVAL_TIME_TZ < SYSTIMESTAMP
ORDER BY 
    A.SNAP_ID;
```

### AWRレポート関数の使用

- 特段の必要性がなければ、テキスト形式のAWRレポート関数を使用
- AWRレポート関数はテーブル関数である
- シグネチャはALL_ARGUMENTSを確認する

```sql
SELECT OUTPUT
FROM TABLE(DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_TEXT(DBID, INSTANCE_NUMBER, SNAP_ID_START, SNAP_ID_END));
```

### 判定フローのまとめ
```
[START] AWRレポート生成リクエスト
    |
    v
[STEP 1] CDB/PDB環境を判定(SYS_CONTEXTで確認)
    |
    +---> CON_ID = 0 (Non-CDB) または CON_ID = 1 (CDB$ROOT)
    |         |
    |         v
    |     DBA_HIST_SNAPSHOT を使用
    |     DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_TEXT を使用
    |
    +---> CON_ID >= 2 (PDB)
              |
              v
          AWR_PDB_SNAPSHOT を使用
          DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_TEXT を使用
```

---

## ハルシネーション防止の検証

### レスポンス前チェックリスト

クエリ結果をユーザーに提供する前に、以下のすべてを確認する:

| チェック | 質問 |
|----------|------|
| [ ] | 実際のクエリを実行したか(DESCRIBEやCOUNTだけではなく)? |
| [ ] | 実際のツール出力から結果を報告しているか(仮定ではなく)? |
| [ ] | ツールが失敗した、または何も返さなかった場合、その事実を明確に述べているか? |
| [ ] | ORA-00904発生時はDESCRIBEを実行してからSQLを修正したか? |

すべてのチェックを確認できない場合、クエリ結果を提供してはならない。

### よくある間違いパターン

[FORBIDDEN] 誤ったパターン:
1. DESCRIBEを実行
2. COUNT(*)を実行
3. 実際のクエリをスキップ ← ルール違反
4. スキーマ/カウント情報に基づいて結果を捏造または仮定

[CORRECT] 正しいパターン:
1. DESCRIBEを実行
2. COUNT(*)を実行
3. 実際のクエリを実行 ← 必須
4. 実際のツール出力からのみ結果を報告

### ツール失敗時の正しい応答
```
「ツールの実行がタイムアウトしました。結果を取得できませんでした。
再実行しますか?または条件を変更しますか?」
```

### ツール失敗時の誤った応答

[FORBIDDEN] 以下のような応答は禁止:
```
「ツールはおそらくAWRデータのサマリーを返したと思われます。」
```

今回設定した Cline Global Rules の概要

1. ORA-00904(invalid identifier)エラー時の必須対応

  • 絶対禁止: DESCRIBEを実行せずにカラム名を推測して修正すること
  • 必須: エラー発生 → DESCRIBE実行 → カラム確認 → 修正理由説明 → 修正SQL実行

2. SQLクエリの3ステップ実行ルール

ステップ 内容
1 DESCRIBE でテーブル構造を確認
2 COUNT(*) で行数を検証(1000行超は要確認)
3 実際のクエリを実行(このステップは必須)

3. MCPツール実行の原則

  • 結果は実際のツール出力のみを信頼する
  • 結果を推測・仮定・捏造しない
  • ツール失敗時は「取得できなかった」と明示し、再試行を確認

4. PL/SQLパッケージ呼び出し前の確認

  • ALL_ARGUMENTSでシグネチャを必ず確認してから実行
  • パラメータを推測で追加しない

5. AWRレポート生成時の注意

  • PDB環境ではv$databaseからDBIDを取得しない
  • AWR_PDB_SNAPSHOTGV$INSTANCEをジョインして確認

6. 共通の禁止事項

  • 同じクエリの繰り返し実行
  • メタデータ確認なしの修正
  • ツール結果の捏造・補完
  • URLの提示

これはあくまでも今回やってみた例ですので「正解」のたぐいではありません。PDBの AWRレポートを強制しているのも用途によっては正しいとは限りませんし、使っているうちに決めておくと良いルールが他にも見えてくると思います。使い込んでいく中でブラッシュアップしていくものです。
AI活用では正解がわからないので始めないは命取り!

実際にやってみる

計画を立てる

Cline には、AIエージェントのタスク処理の計画を立てる Plan モードと、立てた計画を実行する Act モードがあります。まずは、Plan ノードで計画を立てます。

  • VS Code の左アクティビティバーで Cline(ロボットの顔)を選択して Cline を起動します
  • 画面下部のチャット窓に以下のようなプロンプトを入力
AWRレポート生成分析のプロンプト
AWRレポート関数で過去24時間のAWRレポートを生成して分析し、問題のあるSQLの素性(誰がいつ実行したか?、頻度は?、対象としているオブジェクトは何か?、どのような処理を行っているか?、SYSなどのシステムで実行されているSQLやジョブである場合は、それが起動される原因となっているユーザー操作)を突き止めて具体的な改善策を提案する計画を立ててください。
  • 右下の「Plan」を選択

image.png

  • 送信ボタンをクリック

ここから、AIエージェントとの対話が始まります。確率的な動作をする AI モデルですので毎回動きが少しづつ異なりますが例えば以下のように進行します。

最初に MCPサーバーの list-connections ツールを使って利用可能なDB接続の一覧を取得します
image.png

次に、利用可能なDB接続の中からどれを利用するかをユーザーに確認します
image.png

次に、connect ツールを使って、データベースへ接続します
image.png

次に、AWRスナップショットに関する情報を取得するための DBID、インスタンス番号、スナップショットIDを取得するために、AWR_PDB_SNAPSHOTビューの構造を確認します
image.png

次に、実際にAWR_PDB_SNAPSHOTビューからDBID、インスタンス番号、スナップショットIDを取得するSQLを run-sqlcl ツールを使って実行します

image.png

ここまでで、計画立案に必要な情報を取得できたので計画を立案して、ユーザーに確認を求めます
image.png
image.png

計画を実行する

右下の「Act」をクリックして Act モードへ切り替えます

image.png

計画に従って、AWRレポート生成と分析が実行されます
image.png

AWRレポートは、3,633行もありましたので残りは割愛します

取得したAWRレポートから問題があると特定された SQL の詳細を調べるため DBA_HIST_SQLTEXT ビューが検索されます

image.png

問題があるのは、DBMS_CLOUD_PIPELINE関連PL/SQL/SQLで、ベクタインデックス作成処理であることが特定されました。
image.png

最後にレポートが表示されます
image.png
image.png

AWRレポート生成と分析のワークフロー

AIモデルは確率的な動作をしますので、実行する度に動作手順が異なることがありますし、ときには多くの間違いをしてしまうことがあります。そこで、Cline には、実行手順をあらかじめ定義しておくことができる Workflows という機能があります。Workflows も Global Level の Global Workflows と Workspace レベルの Workspace Workflows があります。今回は、Global Workflows に AWRレポート生成と分析のワークフローを定義してみました。なお、このワークフロー自体も 私が手作業で書いたのではなく、上記のように Cline に計画を立てさせて実行した手順の中で良かったものを AIアプリ(今回は Claude Desktop)にワークフローとしてまとめてもらいました

ワークフローをまとめたプロンプト
プロンプト
添付ファイルは、Cline の plan モードで生成された AWRレポート生成と問題SQL分析の実行計画です。この計画を元に Cline の Workflow を作成してください。Cline の Workflow の説明はhttps://docs.cline.bot/features/slash-commands/workflows にあります。特に Workflow Structure Example のセクションを参考にしてください。

ワークフローの概要

ワークフローを定義する

Global Workflows を設定するには以下の手順を踏みます

  • 画面下部の「@」、「+」、ハンバーガーメニューのとなりにある天秤ばかりのボタンをクリック

image.png

  • 「Workflows」タブを選択
  • Global Workflows 直下にワークフローの名前を入力
  • 右の「+」をクリック
  • エディターが開くのでワークフローを入力
  • エディターを閉じる
  • 右端にあるスライダースイッチが青くなっていることを確認

image.png

今回入力したワークフローはこちらです

AWRレポート生成分析ワークフローの詳細
# AWRレポート生成と問題SQL分析ワークフロー

このワークフローは、Oracle Database(CDB/PDB環境)で過去24時間のAWRレポートを生成し、問題SQLを特定して詳細な素性調査と改善策提案を行います。

> **重要なルール(すべてのステップで遵守):**
> - **3ステップルール**: すべてのクエリで `DESCRIBE → COUNT → 実際のクエリ` の順序を守る
> - **ORA-00904対応**: カラムエラー発生時は必ずDESCRIBEを実行してから修正
> - **PDB環境**: `AWR_PDB_SNAPSHOT` を使用(`DBA_HIST_SNAPSHOT` ではない)
> - **PL/SQLシグネチャ**: `ALL_ARGUMENTS` で必ず確認してから実行
> - **MCPツール**: すべてのクエリは `sqlcl:run-sqlcl` ツール経由で実行

---

## Phase 1: 環境準備とAWRレポート生成

### 1.1 データベース接続の確立

1. **利用可能な接続をリスト表示:**
   `sqlcl:list-connections` ツールを使用して、利用可能な接続を表示する。

2. **接続の選択:**
   ユーザーに使用する接続を選択してもらう。

3. **データベースに接続:**
   `sqlcl:connect` ツールを使用して、選択された接続に接続する。

### 1.2 AWRスナップショット情報の取得

**重要**: PDB環境では必ず `AWR_PDB_SNAPSHOT` を使用すること。

1. **テーブル構造の確認:**
   ```sql
   DESCRIBE AWR_PDB_SNAPSHOT
   ```

2. **過去24時間のスナップショット件数を確認:**
   ```sql
   SELECT COUNT(*) as snapshot_count 
   FROM AWR_PDB_SNAPSHOT A, GV$INSTANCE I 
   WHERE A.INSTANCE_NUMBER = I.INSTANCE_NUMBER 
     AND END_INTERVAL_TIME_TZ >= SYSTIMESTAMP - INTERVAL '24' HOUR
   ```

3. **スナップショット情報を取得:**
   ```sql
   SELECT A.DBID, I.INSTANCE_NUMBER, A.SNAP_ID, 
          A.BEGIN_INTERVAL_TIME_TZ, A.END_INTERVAL_TIME_TZ
   FROM AWR_PDB_SNAPSHOT A, GV$INSTANCE I 
   WHERE A.INSTANCE_NUMBER = I.INSTANCE_NUMBER 
     AND END_INTERVAL_TIME_TZ >= SYSTIMESTAMP - INTERVAL '24' HOUR
     AND END_INTERVAL_TIME_TZ < SYSTIMESTAMP
   ORDER BY SNAP_ID
   ```

4. **取得した情報から以下を記録:**
   - DBID
   - INSTANCE_NUMBER
   - 開始SNAP_ID(最小値)
   - 終了SNAP_ID(最大値)

### 1.3 AWRレポート関数のシグネチャ確認

**必須**: `ALL_ARGUMENTS` でシグネチャを確認してから実行する。

```sql
SELECT argument_name, position, data_type, defaulted, in_out
FROM all_arguments
WHERE package_name = 'DBMS_WORKLOAD_REPOSITORY'
  AND object_name = 'AWR_REPORT_TEXT'
ORDER BY position
```

### 1.4 AWRレポート生成

確認したシグネチャに基づいて、AWRレポートを生成する:

```sql
SELECT OUTPUT
FROM TABLE(DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_TEXT(
    <DBID>, 
    <INSTANCE_NUMBER>, 
    <開始SNAP_ID>, 
    <終了SNAP_ID>
))
```

**レポートから以下のセクションを特に注目して分析:**
- Top Wait Events(待機イベント)
- Top SQL by Elapsed Time
- Top SQL by CPU Time
- Top SQL by Gets
- Top SQL by Executions

---

## Phase 2: AWRレポートの分析と問題SQLの特定

### 2.1 問題SQLの抽出(CPU時間が高いSQL Top 10)

1. **DBA_HIST_SQLSTAT の構造確認:**
   ```sql
   DESCRIBE DBA_HIST_SQLSTAT
   ```

2. **対象期間のレコード数確認:**
   ```sql
   SELECT COUNT(*) as record_count
   FROM DBA_HIST_SQLSTAT
   WHERE snap_id BETWEEN <開始SNAP_ID> AND <終了SNAP_ID>
     AND dbid = <DBID>
   ```

3. **CPU時間が高いSQL Top 10を取得:**
   ```sql
   SELECT sql_id, 
          SUM(cpu_time_delta)/1000000 as cpu_seconds,
          SUM(elapsed_time_delta)/1000000 as elapsed_seconds,
          SUM(executions_delta) as executions,
          SUM(buffer_gets_delta) as buffer_gets
   FROM DBA_HIST_SQLSTAT
   WHERE snap_id BETWEEN <開始SNAP_ID> AND <終了SNAP_ID>
     AND dbid = <DBID>
   GROUP BY sql_id
   ORDER BY cpu_seconds DESC
   FETCH FIRST 10 ROWS ONLY
   ```

4. **問題SQLのSQL_IDリストを記録する。**

---

## Phase 3: 問題SQLの素性調査(各SQL_IDについて繰り返す)

以下のステップを、特定した各問題SQL_IDに対して実行する。

### 3.1 誰が実行したか?(Who)

1. **DBA_HIST_ACTIVE_SESS_HISTORY の構造確認:**
   ```sql
   DESCRIBE DBA_HIST_ACTIVE_SESS_HISTORY
   ```

2. **該当SQL_IDのレコード数確認:**
   ```sql
   SELECT COUNT(*) as record_count
   FROM DBA_HIST_ACTIVE_SESS_HISTORY
   WHERE sql_id = '<SQL_ID>'
     AND snap_id BETWEEN <開始SNAP_ID> AND <終了SNAP_ID>
     AND dbid = <DBID>
   ```

3. **実行ユーザー情報を取得:**
   ```sql
   SELECT DISTINCT 
       h.user_id,
       u.username,
       h.module,
       h.action,
       h.program,
       h.client_id
   FROM DBA_HIST_ACTIVE_SESS_HISTORY h
   LEFT JOIN dba_users u ON h.user_id = u.user_id
   WHERE h.sql_id = '<SQL_ID>'
     AND h.snap_id BETWEEN <開始SNAP_ID> AND <終了SNAP_ID>
     AND h.dbid = <DBID>
   ```

### 3.2 いつ・どのくらいの頻度で実行されたか?(When & Frequency)

```sql
SELECT 
    TO_CHAR(s.end_interval_time_tz, 'YYYY-MM-DD HH24') as hour,
    SUM(st.executions_delta) as executions,
    SUM(st.cpu_time_delta)/1000000 as cpu_seconds,
    SUM(st.elapsed_time_delta)/1000000 as elapsed_seconds
FROM DBA_HIST_SQLSTAT st
JOIN AWR_PDB_SNAPSHOT s ON st.snap_id = s.snap_id 
    AND st.dbid = s.dbid 
    AND st.instance_number = s.instance_number
WHERE st.sql_id = '<SQL_ID>'
  AND st.snap_id BETWEEN <開始SNAP_ID> AND <終了SNAP_ID>
  AND st.dbid = <DBID>
GROUP BY TO_CHAR(s.end_interval_time_tz, 'YYYY-MM-DD HH24')
ORDER BY hour
```

### 3.3 対象としているオブジェクトは何か?(What Objects)

1. **DBA_HIST_SQL_PLAN の構造確認:**
   ```sql
   DESCRIBE DBA_HIST_SQL_PLAN
   ```

2. **アクセスしているオブジェクトを取得:**
   ```sql
   SELECT DISTINCT 
       object_owner,
       object_name,
       object_type,
       operation,
       options
   FROM DBA_HIST_SQL_PLAN
   WHERE sql_id = '<SQL_ID>'
     AND dbid = <DBID>
     AND object_name IS NOT NULL
   ORDER BY object_owner, object_name
   ```

### 3.4 どのような処理を行っているか?(What Processing)

1. **SQL文のテキストを取得:**

   **DBA_HIST_SQLTEXT の構造確認:**
   ```sql
   DESCRIBE DBA_HIST_SQLTEXT
   ```

   **SQL文を取得:**
   ```sql
   SELECT sql_text
   FROM DBA_HIST_SQLTEXT
   WHERE sql_id = '<SQL_ID>'
     AND dbid = <DBID>
   ```

2. **実行計画の詳細を取得:**

   まず、PLAN_HASH_VALUEを特定:
   ```sql
   SELECT DISTINCT plan_hash_value 
   FROM DBA_HIST_SQLSTAT 
   WHERE sql_id = '<SQL_ID>' 
     AND snap_id BETWEEN <開始SNAP_ID> AND <終了SNAP_ID>
     AND dbid = <DBID>
   ```

   実行計画を取得:
   ```sql
   SELECT 
       id,
       parent_id,
       operation,
       options,
       object_owner,
       object_name,
       cardinality,
       bytes,
       cost
   FROM DBA_HIST_SQL_PLAN
   WHERE sql_id = '<SQL_ID>'
     AND dbid = <DBID>
     AND plan_hash_value = <PLAN_HASH_VALUE>
   ORDER BY id
   ```

### 3.5 システムSQLやジョブの場合の起動原因特定

**SYSユーザーや自動メンテナンスタスクの場合のみ実行:**

1. **スケジューラージョブの確認:**
   ```sql
   SELECT 
       job_name,
       job_type,
       job_action,
       enabled,
       state
   FROM DBA_SCHEDULER_JOBS
   WHERE job_name LIKE '%AUTO%' 
      OR job_name LIKE '%MAINT%'
   ```

2. **前後の関連アクティビティを確認(必要に応じて):**
   ```sql
   SELECT 
       sample_time,
       session_id,
       module,
       action,
       event,
       wait_class,
       sql_id
   FROM DBA_HIST_ACTIVE_SESS_HISTORY
   WHERE dbid = <DBID>
     AND sample_time BETWEEN 
         (SELECT MIN(sample_time) - INTERVAL '5' MINUTE
          FROM DBA_HIST_ACTIVE_SESS_HISTORY
          WHERE sql_id = '<SQL_ID>' AND dbid = <DBID>)
     AND (SELECT MAX(sample_time) + INTERVAL '5' MINUTE
          FROM DBA_HIST_ACTIVE_SESS_HISTORY
          WHERE sql_id = '<SQL_ID>' AND dbid = <DBID>)
   ORDER BY sample_time
   FETCH FIRST 50 ROWS ONLY
   ```

---

## Phase 4: 改善策の提案

各問題SQLの分析結果に基づいて、以下の観点から改善策を提案する:

### 4.1 改善策の検討ポイント

1. **インデックスの最適化**
   - フルテーブルスキャンが発生しているか?
   - 適切なインデックスが存在するか?
   - インデックスが使用されているか?

2. **SQL文の書き換え**
   - 非効率な結合方法はないか?
   - 不要なソート処理はないか?
   - サブクエリの最適化は可能か?

3. **統計情報の更新**
   - オブジェクト統計は最新か?
   - ヒストグラムが必要か?

4. **アプリケーション側の改善**
   - バッチ処理の最適化
   - 実行頻度の見直し
   - トランザクション設計の改善

5. **システムパラメータの調整**
   - メモリ割り当て
   - パラレル処理の設定

6. **アーキテクチャレベルの改善**
   - パーティショニング
   - マテリアライズドビュー
   - キャッシュ戦略

---

## Phase 5: 最終レポートの作成

以下の形式でレポートを作成し、マークダウンファイルに出力し、その全文とファイル名をユーザーに提示する:

```
=====================================
AWRレポート分析結果(過去24時間)
=====================================

■ 実行期間
開始: [BEGIN_INTERVAL_TIME]
終了: [END_INTERVAL_TIME]
スナップショット範囲: [開始SNAP_ID] - [終了SNAP_ID]

■ 主要な問題領域
1. [問題領域名]
   - 影響度: [高/中/低]
   - 詳細: [説明]

■ 問題SQL一覧

────────────────────────────────────
【SQL #1】SQL_ID: [sql_id]
────────────────────────────────────
問題の種類: [CPU時間が高い / 経過時間が長い / 実行回数が多い]
影響度メトリクス:
  - CPU時間: [X] 秒
  - 経過時間: [X] 秒
  - 実行回数: [X] 回
  - Buffer Gets: [X]

◆ 素性情報
  - 実行ユーザー: [username]
  - MODULE: [module_name]
  - PROGRAM: [program_name]
  - 実行時刻帯: [peak hours]
  - 実行頻度: [X]回/日
  - 対象オブジェクト: [owner.table_name, ...]
  - 処理内容: [SQL文の要約]

◆ SQL文
[SQL text - 長い場合は要約]

◆ 実行計画の問題点
[実行計画の分析結果]
- フルテーブルスキャン: [有/無]
- 問題のある操作: [詳細]

◆ 推奨される改善策
  1. [具体的な改善策1]
     - 実装方法: [詳細]
     - 期待される効果: [効果の見積もり]
  
  2. [具体的な改善策2]
     - 実装方法: [詳細]
     - 期待される効果: [効果の見積もり]

[以下、他の問題SQLも同様に記載]

=====================================
```

---

## 注意事項

- **エラー発生時**: ORA-00904(無効な識別子)が発生した場合は、必ずDESCRIBEを実行してカラム名を確認してから修正する
- **結果なしの場合**: クエリ結果が0件の場合は、条件を緩和するか、別のアプローチを検討する
- **長時間実行**: AWRレポート生成は時間がかかる場合があるため、ユーザーに進捗を報告する
- **推測禁止**: MCPツールの実際の出力のみに基づいて報告し、推測や仮定はしない

AWRレポート生成と分析のワークフローを実行する

チャット窓で"/" に続いてワークフロー名を入力するとワークフローが読み込まれます。
モードは、Plan でも Act でも大丈夫ですが、ワークフロー自体をカスタマイズしたいときは Plan モード、そのまま実行してかまわない場合は Act モードという使い分けになりそうです。

AWRレポート分析結果(過去24時間)の詳細
=====================================
AWRレポート分析結果(過去24時間)
=====================================

■ 実行期間
開始: 2026-01-04 15:01:18 GMT
終了: 2026-01-05 15:01:04 GMT
スナップショット範囲: 5624 - 5647

DBID: 1587474289
INSTANCE_NUMBER: 8

■ 主要な問題領域
1. Vector Index Pipeline Tasks (DBMS_CLOUD_PIPELINE)
   - 影響度: 高
   - 詳細: 過去24時間のCPU時間の大部分を占める。並列タスクによるベクターインデックス作成がDB負荷の主因。AWRレポートでTop SQLとしてfwbhcwv7mmwyy (168,949秒 CPU), 9m93qty91up58 (168,713秒 CPU), fk2sykrjqsu1u (23,890秒 CPU) が特定。待機イベント: DB CPU 96.5%, library cache mutex, resmgr:cpu quantum。

■ 問題SQL一覧

────────────────────────────────────
【SQL #1】SQL_ID: fwbhcwv7mmwyy
────────────────────────────────────
問題の種類: CPU時間が高い
影響度メトリクス:
  - CPU時間: 168,949 秒
  - 経過時間: 174,269 秒
  - 実行回数: 10,391 回
  - Buffer Gets: 20,119,886,938

◆ 素性情報
  - 実行ユーザー: WKSP_APEXDEV, LABUSER, DEVDAY25USER
  - MODULE: DBMS_CLOUD, DBMS_SCHEDULER
  - PROGRAM: 
  - 実行時刻帯: 2026-01-04 16:00 - 2026-01-05 15:00 (ほぼ均等)
  - 実行頻度: 約430回/時間 (総10,391回/24時間)
  - 対象オブジェクト: PL/SQLコールのため、内部的にDBMS_CLOUD_PIPELINEおよび関連テーブル (DBMS_PARALLEL_EXECUTE_CHUNKS$ など)
  - 処理内容: DBMS_CLOUD_PIPELINE.RUN_PIPELINE を呼び出し、Vector Index作成の並列タスクを実行

◆ SQL文
call C##CLOUD$SERVICE.DBMS_CLOUD_PIPELINE.RUN_PIPELINE ( :0,:1 )

◆ 実行計画の問題点
- 実行計画: 利用不可 (PL/SQLコール、plan_hash_value=0)
- フルテーブルスキャン: 内部でDBMS_PARALLEL_EXECUTE_CHUNKS$に対する大規模スキャン/更新が発生
- 問題のある操作: 並列タスクによる高負荷 (CPU 96.9%, I/O 0.5%)

◆ 推奨される改善策
  1. Vector Pipelineの最適化
     - 実装方法: chunk_sizeを増やし (例: 400→800)、chunk_overlapを減らす (128→64)。OCIクレデンシャルとObject Storage URIを確認し、ネットワーク遅延を最小化。
     - 期待される効果: CPU使用率20-30%低減、経過時間15%短縮 (AWRのTop Wait: library cache mutex 0.6%)
  
  2. インデックスの最適化
     - 実装方法: DBMS_PARALLEL_EXECUTE_CHUNKS$に追加インデックス作成 (TASK_OWNER#, TASK_NAME, STATUS)。
     - 期待される効果: SELECT/UPDATEのBuffer Gets低減 (20B→10B以下)、CPU 10%低減

────────────────────────────────────
【SQL #2】SQL_ID: 9m93qty91up58
────────────────────────────────────
問題の種類: CPU時間が高い
影響度メトリクス:
  - CPU時間: 168,713 秒
  - 経過時間: 174,022 秒
  - 実行回数: 10,391 回
  - Buffer Gets: 20,118,135,621

◆ 素性情報
  - 実行ユーザー: WKSP_APEXDEV, LABUSER, DEVDAY25USER
  - MODULE: DBMS_CLOUD
  - PROGRAM: 
  - 実行時刻帯: 2026-01-04 16:00 - 2026-01-05 15:00 (ほぼ均等)
  - 実行頻度: 約430回/時間 (総10,391回/24時間)
  - 対象オブジェクト: 内部的にDBMS_PARALLEL_EXECUTE_CHUNKS$ など
  - 処理内容: run_parallel_task を実行し、チャンク処理の並列化

◆ SQL文
BEGIN DBMS_CLOUD_INTERNAL.run_parallel_task( params => :params, operation_id => :operation_id); END;

◆ 実行計画の問題点
- 実行計画: 利用不可 (PL/SQL)
- フルテーブルスキャン: チャンク処理による大規模アクセス
- 問題のある操作: 並列タスクのスケジューリング (resmgr:cpu quantum 0.3%)

◆ 推奨される改善策
  1. 並列度調整
     - 実装方法: parallel_servers_targetを現在の値から20%低減 (例: 128→102)。resource_manager_planを調整。
     - 期待される効果: Scheduler待機低減 (resmgr:cpu quantum 146ms)、全体CPU 15%低減
  
  2. 統計情報更新
     - 実装方法: DBMS_STATS.GATHER_TABLE_STATS on DBMS_PARALLEL_EXECUTE_CHUNKS$。
     - 期待される効果: Optimizerコスト改善、経過時間10%短縮

────────────────────────────────────
【SQL #3】SQL_ID: fk2sykrjqsu1u
────────────────────────────────────
問題の種類: CPU時間が高い
影響度メトリクス:
  - CPU時間: 23,890 秒
  - 経過時間: 23,765 秒
  - 実行回数: 12,578,091 回
  - Buffer Gets: 77,295,944

◆ 素性情報
  - 実行ユーザー: DEVDAY25USER
  - MODULE: DBMS_CLOUD
  - PROGRAM: 
  - 実行時刻帯: 2026-01-04 16:00 - 2026-01-05 15:00
  - 実行頻度: 約500,000回/時間 (高頻度)
  - 対象オブジェクト: PIPELINE$xx$xx_STATUSテーブル
  - 処理内容: run_parallel_task_chunk でベクターインデックスチャンク処理

◆ SQL文
BEGIN DBMS_CLOUD_INTERNAL.run_parallel_task_chunk( params => '{"invoker_schema":"DEVDAY25USER",...}...', start_id => :start_id, end_id => :end_id ); END;

◆ 実行計画の問題点
- 実行計画: 利用不可 (PL/SQL)
- フルテーブルスキャン: ステータス確認のSELECTで発生
- 問題のある操作: 高頻度チャンク処理 (12M回実行)

◆ 推奨される改善策
  1. SQL文の書き換え
     - 実装方法: チャンクSELECTをインデックスベースに変更 (id, status ON PIPELINE$xx$xx_STATUS)。サブクエリ最適化。
     - 期待される効果: Buffer Gets 50%低減、CPU 25%短縮
  
  2. アプリケーション側の改善
     - 実装方法: バッチサイズ増加 (start_id/end_id間隔拡大)、実行頻度見直し (1時間1回→必要時のみ)。
     - 期待される効果: 実行回数30%低減、全体負荷20%低減

[追加のSQL #4-10: 同様にDBMS_CLOUD関連。トップ3が主な負荷源のため、省略。詳細はAWRレポート参照]

=====================================

ワークフロー実行の実シーケンス

mermaid_diagram_20260111_003941.png

補足1(2026年2月25日追記)

AWRレポートのような大きなデータをファイルに書きだそうとするとファイルの一部しか書き出されなかったり Cline のファイル操作ツール呼び出しが失敗してしまうことがあります。
そんな場合の TIPS を下記のブログに書きました。

補足2(2026年3月8日追記)

上記の TIPS(MCPツールから返されるデータが大きい場合に CLI のスクリプトを活用する方法)を使った Cline WOrkflow の紹介ブログを書きました。

Next Step - Agent Skills

この記事では、ルールやワークフローによってエージェントをガイドすることをご紹介しましたが、最近注目されている Agent Skills に Cline も対応(experimental)しました。Skills を使って AWRレポート生成分析を行う記事も書きました。Cline を使った AIOps を実践していくと AWRレポート以外のルールが沢山必要になって来ます。そのようなときに役に立つのが Skills です。

あとがき

Cline のようなコーディングAIエージェントを使って、Plan モードで計画を立てて、Act モードで実行、そして、こなれた計画をワークフロー化するという手順はなかなか良いように感じました。このようなワークフローをブラッシュアップして蓄積していくことで運用業務を効率化することができそうです。お試しあれ。

19
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?