huawei-cloud-dws-cpu-diag について
Huawei Cloud DWS クラスターの CPU 使用率上昇を診断するスキルです。アラートや負荷異常を調べる運用担当者向けに、メトリクスを収集・分析し、標準形式のレポートを作成します。
主な機能
- 01クラスターの CPU と関連メトリクスを収集
- 02ノード負荷と業務同時実行数を分析
- 03クエリとプロセスの CPU データを確認
- 04KooCLI を使用し、必要に応じて MCP に切り替え
- 05標準形式の診断レポートを作成
活用シーン
- 01DWS クラスターの CPU アラートを調査
- 02クラスター負荷異常の原因を特定
- 03依頼された CPU 診断への対応
MCP 対応
KooCLI が利用できない場合、dws_autopilot MCP サーバーを代替手段として使い、クラスター、ホスト、メトリクスを照会できます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ huaweicloud/ huaweicloud-skills --skill huawei-cloud-dws-cpu-diagインストール後、Claude Code で/huawei-cloud-dws-cpu-diagを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/dws-mcp-installation-guide.mdiam-policies.mdmetric-reference.md詳細
Huawei Cloud DWS CPU 高負荷診断スキル
概要
このスキルは、DWS クラスターの CPU 高負荷の根本原因診断に特化しています。クラスターで CPU 使用率が高すぎるというアラームが発生すると、メトリクスデータを自動的に収集し、根本原因(顧客側/システム側)を分析して、標準化された診断レポートを出力します。
アーキテクチャ:KooCLI (hcloud) → DWS Autopilot API → クラスター監視メトリクス;MCP サーバー (dws_autopilot) → 同じ API のフォールバックチャネル
対象シナリオ:
- DWS クラスターの CPU 使用率が高すぎるというアラーム
- CPU 負荷の異常調査
- ユーザーが開始する CPU 診断リクエスト
代表的なユースケース:
- 「DWS クラスターの CPU 使用率が非常に高いので、診断してください」
- 「CPU アラームを受信しました。クラスター ID は xxx です。原因を分析してください」
- 「DWS クラスターの CPU が上限に達しています。原因を調べてください」
重要なルール:診断結果はすべて、実際のツールの戻り値に基づく必要があります。値を捏造または推測することは禁止されています。出力に含めるのは診断レポートのみです。改善策の提案、SQL 最適化ステートメントの出力、絵文字の使用は禁止されています。
前提条件
1. CLI の要件
- KooCLI (hcloud) >= 3.2.0
- インストールの確認:
hcloud version - 未インストールの場合、またはバージョンが古い場合は、CLI インストールガイドを参照してください
2. MCP サーバーの設定(フォールバック)
- KooCLI を利用できない場合は、代替手段として MCP サーバーを使用します
- MCP インストールガイドを参照してください
3. 認証の設定
- 有効な Huawei Cloud 認証情報(AK/SK モードまたは IAM Token)
- セキュリティルール:
- 会話やコマンドで AK/SK の値を公開しないでください
- 会話内でユーザーに AK/SK を直接入力するよう求めないでください
- 認証情報の状態確認には
hcloud configure listのみを使用してください
4. IAM 権限の要件
- dws:clusters:get、dws:clusters:list
- dws:metricData:get、dws:hostOverview:get
- IAM ポリシーを参照してください
KooCLI コマンド形式の標準
コマンド形式
# Query metric data
hcloud DWS ListMetricsData --cli-region=<region> --cluster_id=<id> --metric_name=<name> --project_id=<pid> --offset=0 --limit=200 --from=<from_ts> --to=<to_ts>
# Query host information
hcloud DWS ListHostOverview --cli-region=<region> --project_id=<pid> --offset=0 --limit=200
ツール選択戦略
KooCLI と MCP サーバーのいずれかを選択します。KooCLI を優先します。ステップ 0 で hcloud が利用可能か確認します。
- hcloud が利用可能(バージョン >= 3.2.0)→ 以降のステップでは KooCLI コマンドライン呼び出しを使用します
- hcloud が利用不可(未インストール、またはバージョン < 3.2.0)→ 以降のステップでは MCP サーバーのツール呼び出しを使用します
フォールバックと終了の戦略:
- hcloud を選択した後、最初の呼び出しで
NETWORK_ERROR(接続タイムアウト、ネットワーク到達不可など)が返された場合は、自動的に MCP サーバーにフォールバックし、以降のすべてのステップで MCP モードを使用します - hcloud が NETWORK_ERROR を返し、MCP サーバーも利用不可(未設定、または認証/接続エラーを返す)の場合、このスキルを終了し、次のメッセージを出力します:
KooCLI network unavailable and MCP Server connection failed. Please check KooCLI network configuration or DWS Autopilot MCP Server configuration and retry - MCP サーバーを選択した後、最初の呼び出しで認証エラー(例:401 Unauthorized)が返された場合、hcloud にはフォールバックしません。このスキルを直ちに終了し、次のメッセージを出力します:
MCP Server authentication failed. Please check DWS Autopilot MCP Server authentication configuration and retry - NETWORK_ERROR 以外の hcloud 呼び出し失敗(例:パラメーターエラー、権限不足)ではフォールバックしません。既存の再試行ロジックに従ってください
ツールを選択したら、NETWORK_ERROR のフォールバックを除き、切り替えずに最後まで使用してください。呼び出しに失敗した場合は 1 回再試行します(最大 2 回)。それでも失敗する場合は、そのメトリクスを「利用不可」としてマークし、次のステップに進みます。すべてのメトリクスのクエリに失敗した場合は、そのまま診断レポートを生成します。
パラメーターの対応
| 共通パラメーター | hcloud パラメーター | MCP パラメーター |
|---|---|---|
| リージョン | --cli-region | (MCP 接続に組み込み済み) |
| プロジェクト ID | --project_id | project_id |
| クラスター ID | --cluster_id | cluster_id |
| メトリクス名 | --metric_name | metric_name |
| 開始時刻 | --from | from_ts |
| 終了時刻 | --to | to_ts |
| ページネーションのオフセット | --offset | offset |
| ページネーションの上限 | --limit | limit |
| ソートフィールド | (未対応) | order_by |
| ソート方向 | (未対応) | sort_by |
MCP ツール
| ツール名 | 用途 |
|---|---|
dws_autopilot_get_clusters | クラスター一覧を照会し、クラスター名や project_id などを取得します。 |
dws_autopilot_get_hosts | ホスト情報を照会します。 |
dws_autopilot_get_metric | メトリクスデータを照会します。 |
利用可能な metric_name:CpuStat、business_concurrency、cpu_io_diagnose_detail、node_process_cpu_top20、command_cpu_usage
メトリクスごとの主要フィールドと、手順ごとのクエリの違いについては、メトリクスリファレンスを参照してください。
ページネーション仕様
単一の応答が大きくなりすぎてトークン制限を超えないように、すべてのツール呼び出し(MCP および hcloud)でページネーション付きクエリを使用する必要があります。
ページネーションのルール:
- 一律で
limit=200を使用します(800 やその他の大きな値は使用しないでください)。 - 最初のページでは
offset=0を指定します。返されたデータ件数が 200 の場合はoffset+=200として、クエリを続けます。 - 返されたデータ件数が 200 未満になるまで繰り返し、最後にすべてのページのデータを統合します。
- データを統合する際は、各ページのデータ配列を連結して完全なデータセットにします。
MCP 呼び出し例(CpuStat を使用):
Page 1: dws_autopilot_get_metric(project_id, cluster_id, metric_name="CpuStat", from_ts, to_ts, limit=200, offset=0)
If returned data length = 200:
Page 2: dws_autopilot_get_metric(project_id, cluster_id, metric_name="CpuStat", from_ts, to_ts, limit=200, offset=200)
If returned data length < 200: Stop pagination, merge page 1 + page 2 data
hcloud 呼び出し例(CpuStat を使用):
Page 1: hcloud DWS ListMetricsData --cli-region=<region> --cluster_id=<id> --metric_name=CpuStat --project_id=<pid> --offset=0 --limit=200 --from=<from_ts> --to=<to_ts>
If returned data count = 200:
Page 2: hcloud DWS ListMetricsData --cli-region=<region> --cluster_id=<id> --metric_name=CpuStat --project_id=<pid> --offset=200 --limit=200 --from=<from_ts> --to=<to_ts>
If returned data count < 200: Stop pagination, merge data
ワークフロー
診断を始める前に、ステップ 0~7 に基づいて実行計画を作成し、その後、順番に実行してください。ツールの選択方針については、「KooCLI コマンド形式標準」セクションを参照してください。以降のステップでは、この説明を繰り返しません。MCP ツールの呼び出しはすべて「ページネーション仕様」セクションに従ってください。以降のステップでは、ページネーションの詳細を繰り返しません。
ステップ 0:環境の検出
hcloud version を実行します。バージョンが 3.2.0 以上の場合は tool_mode=hcloud、それ以外の場合は tool_mode=mcp とします。
hcloud のネットワーク疎通確認:tool_mode=hcloud の場合、軽量な API 呼び出し(例:hcloud DWS ListClusters --cli-region=<region> --project_id=<project_id> --offset=0 --limit=1)を実行して、ネットワーク接続を確認します。
- 正常な応答、または業務エラー(権限不足、パラメーターエラーなど)が返された場合 → ネットワークは利用可能です。tool_mode=hcloud を維持します。
- NETWORK_ERROR が返された場合 → ネットワークは利用できません。tool_mode=mcp に切り替えます。
- フォールバック後、MCP も利用できない場合 → 実行を終了し、KooCLI のネットワーク設定または MCP サーバーの設定を確認するようユーザーに促します。
Step 1: CpuStat をクエリする
metric_name="CpuStat" を指定してメトリクスクエリを呼び出します。時間範囲は from_ts=first_alarm_time - 1200000、to_ts=first_alarm_time です。MCP モードでは、limit=200 でページネーション付きクエリを使用します。
Autopilot が利用できない場合の判定:project_id が空、または 50201/RDS.9999 エラーが返された場合は、ステップ 1~5.5 をスキップし、すべてのメトリクスを「利用不可」として、ステップ 6 に直接進みます。
解析:CPU 使用率 = usr + sys です。host_id ごとにグループ化し、各ノードについて、CPU 使用率の最大値と平均値(時間範囲全体)を個別に計算します。
TOP ノードの絞り込み:ノードを平均 CPU 使用率の降順で並べ替え、TOP ノードを選択します。
- クラスターのノード数が 6 以下:すべてのノードを選択します
- クラスターのノード数が 6 より多い:TOP 3 ノードのみを選択します
ノード範囲の分類:すべてのノードで CPU 使用率が高い(高 CPU ノードの比率が 80% 以上)場合 → all_nodes、単一ノードで CPU 使用率が高い場合 → single_node、一部のノードの場合 → partial_nodes。
負荷分散の判定:TOP ノードについて、CPU 使用率の最大値と平均値の差を比較します。すべての TOP ノードで |max - avg| / avg < 20% の場合は「負荷分散あり」とし、以降のステップ(ステップ 4~5.5)では TOP 3 ノードのみを分析します。それ以外の場合は「負荷分散なし」とし、以降のステップでは CPU 使用率の高いすべてのノードを分析します。
出力:cpu_by_host、max_cpu_hosts(平均 CPU 使用率順に並べた TOP ノードのリスト)、problem_host_id、problem_host_cpu_usage、cpu_scope、high_cpu_nodes、is_balanced、nodes_to_analyze(以降のステップで分析するノードのリスト)
Step 2: ホスト名を取得する
ホスト情報クエリを呼び出し(MCP モードでは limit=200 でページネーションを使用)、host_id → {host_name, ip} の対応表を作成します。ステップ 1 の出力にある nodes_to_analyze の対象ノードについてのみ、ホスト情報をクエリします。
出力:host_id_to_info_map、problem_host_ip、node_name
Step 3: ビジネス同時実行数をクエリする
metric_name="business_concurrency" を指定してメトリクスクエリを呼び出します。MCP モードでは、limit=200 でページネーション付きクエリを使用し、返された件数が 200 未満になるまでクエリを続けます。
出力:max_concurrency、avg_concurrency、is_high_concurrency
Step 4: CPU 使用率が最も高いノードの診断詳細をクエリする
metric_name="cpu_io_diagnose_detail" を指定してメトリクスクエリを呼び出します。host_id による絞り込みには対応していないため、クラスター全体をクエリしてから、ステップ 1 の出力にある nodes_to_analyze で絞り込みます。MCP モードでは limit=200 のページネーション付きクエリを必ず使用してください(このメトリクスはデータ量が最も多く、800 件を 1 ページで取得するとトークン上限を超えます)。返された件数が 200 未満になるまでクエリを続け、絞り込みの前にページネーションで取得したすべてのデータを結合します。
解析:アクティブなクエリ、ユーザー、実行時間、プロセス情報を抽出します。ctime は収集時刻であり、SQL の開始時刻ではありません。duration_ms が存在する場合、SQL の開始時刻 = ctime - duration_ms です。state=active のユーザーのみをカウントします。inst_name に "cn" が含まれている場合は CN インスタンス、"dn" が含まれている場合は DN インスタンスです。
注:cpu_io_diagnose_detail は、ネストされた active_queries 配列ではなく、フラットな行構造(1 行につき 1 つのクエリレコード)を返します。主なフィールド:ctime、host_id、inst_name、username、cpu_rate、count、datname、io_read、io_write、query_id、query、duration_ms、state。
出力:single_statement_detected、single_statement_info、high_concurrency_detected、concurrent_stats、inst_type、high_freq_queries、heavy_queries
Step 5: プロセス CPU 使用率 TOP 20 をクエリする
metric_name="node_process_cpu_top20" を指定してメトリクスクエリを呼び出します。MCP モードでは、limit=200 でページネーション付きクエリを使用します。クラスター全体をクエリしてから、ステップ 1 の出力にある nodes_to_analyze で絞り込みます。注:このメトリクスは null を返すことがあります。その場合は「利用不可」として、スキップします。
出力:processes_by_host、top_cpu_process
ステップ 5.5:コマンドレベルの CPU 使用率をクエリする
metric_name="command_cpu_usage" を指定して、メトリッククエリを呼び出します。MCP モードでは、limit=200 を指定したページネーション付きのクエリを使用します。
データ構造:各行は、あるホスト上のプロセスを、ある収集時刻に記録したものです。主なフィールドは、ctime、host_id、command、args(command_detail)、cpu_rate、username です。command フィールドでプロセスの種類を区別します。例:gaussdb-dn(データノードのメインプロセス)、gaussdb-cn(コーディネーターのメインプロセス)、gaussdb(fenced UDF サブプロセス)、python3、java、sh、cm_agent、gs_gtm など。args フィールドには、完全なコマンドの詳細が含まれます(例:/DWS/manager/app/bin/gaussdb --datanode ...)。username フィールドはOS ユーザー(例:Ruby、root)であり、データベースユーザーではありません。
Gaussdb メインプロセスの定義:command フィールドが gaussdb-dn または gaussdb-cn の場合は、gaussdb のメインプロセスです(その CPU 使用率は SQL 文と根本原因に帰属し、「プロセストップ 3」から除外します)。command フィールドが gaussdb(fenced UDF マスタープロセス)の場合は、メインプロセスではなく、「プロセストップ 3」に含めます。
出力:command_by_host、abnormal_process
ステップ 6:診断結果を分析する
診断の優先順位:まず対象範囲を確認してから原因を特定します。ビジネス上の異常を先に確認し、設定とシステムの問題は最後に確認します。
CPU の種類の判定:SysCPU/UserCPU >= 1/2 の場合は SysCPU 高負荷、それ以外の場合は UserCPU 高負荷です。
ユーザー種別の判定:データベースユーザー(userName)が omm/Ruby の場合はシステム起因、それ以外の場合はお客様側の起因です。
異常プロセスの特定:command に safest/AsiaInfo/aliyundun が含まれる場合はウイルス対策ソフトです。command に gaussdb/postgres/gtm/cm_agent が含まれない場合は、gaussdb 以外のプロセスです。command が gaussdb(fenced UDF。gaussdb-dn/gaussdb-cn ではない)の場合は、サブプロセスの異常です。
お客様側の原因:高い同時実行数(複数ユーザー/単一ユーザー)、単一文(CPU 比率 > 30%)、データスキュー/計算スキューです。高い同時実行数と単一文は、同時に該当する場合があります。
システム側の原因:システム内部の SQL(VACUUM など)、異常プロセス、SysCPU 高負荷です。
統計:次の 3 種類の「トップ 3」を算出します。
- 文トップ 3(cpu_io_diagnose_detail から):cpu_rate の降順で並べ替えます(cpu_rate はすでにインスタンス単位の割合なので、そのまま使用します)。query_id、username、開始時刻、CPU 比率、具体的な SQL(最大 1024 文字)を出力します。各行は 1 つのインスタンス上の 1 つのクエリです。グローバル合計で割って比率を再計算しないでください。
- データベースユーザーのトップ 3(cpu_io_diagnose_detail から):username ごとに cpu_rate を集計します(state=active のみ)。username と比率を出力します。ここでの username はデータベースユーザーであり、OS ユーザーではありません。比率 = ユーザーの cpu_rate 合計 / 全ユーザーの cpu_rate 合計 × 100%。
- OS プロセスのトップ 3(command_cpu_usage から):command ごとに cpu_rate を集計します。gaussdb のメインプロセス(command が
gaussdb-dnまたはgaussdb-cn)を除外し、残りのプロセスを cpu_rate の降順で並べ替えて、上位 3 件を取得します。注:gaussdb(fenced UDF)はメインプロセスではないため、含めてください。command_cpu_usage の username フィールドはOS ユーザーであり、データベースユーザーとは異なります。混同しないでください。比率 = プロセスの cpu_rate 合計 / メインプロセス以外の全プロセスの cpu_rate 合計 × 100%。
ステップ 7:診断レポートを生成する
「出力形式」セクションのテンプレートに従って、HTML レポートを生成します。レポートの生成後、現在の作業ディレクトリ(ワークスペースのルートフォルダー)に、ファイル名 dws_cpu_diagnosis_report_{timestamp}.html で HTML ファイルを保存してください。{timestamp} は、現在のマシンのローカル時刻を yyyyMMdd_HHmmss 形式で表したものです(例:dws_cpu_diagnosis_report_20260623_150421.html)。
コアコマンド
クラスターリストをクエリする
# hcloud
hcloud DWS ListClusters --cli-region=<region> --project_id=<pid> --offset=0 --limit=200
# MCP
dws_autopilot_get_clusters(project_id=<pid>)
ホスト情報をクエリする
# hcloud
hcloud DWS ListHostOverview --cli-region=<region> --project_id=<pid> --offset=0 --limit=200
# MCP
dws_autopilot_get_hosts(project_id=<pid>, cluster_id=<cid>, limit=200, offset=0)
メトリックデータをクエリする(一般形式)
# hcloud
hcloud DWS ListMetricsData --cli-region=<region> --cluster_id=<cid> --metric_name=<name> --project_id=<pid> --offset=0 --limit=200 --from=<from_ts> --to=<to_ts>
# MCP
dws_autopilot_get_metric(project_id=<pid>, cluster_id=<cid>, metric_name=<name>, from_ts=<from>, to_ts=<to>, limit=200, offset=0, order_by="ctime", sort_by="desc")
パラメーターの確認
| パラメーター | 必須/任意 | 説明 | デフォルト |
|---|---|---|---|
| alarm_serial_number | 必須 | アラームのシリアル番号 | N/A |
| project_id | 必須 | プロジェクト ID | N/A |
| cluster_id | 必須 | クラスター ID | N/A |
| first_alarm_time | 必須 | 最初のアラーム時刻(ミリ秒単位のタイムスタンプ) | N/A |
| alarm_name | 必須 | アラーム名 | N/A |
| region_id | 任意 | リージョン識別子 | N/A |
| node_name | 任意 | アラート対象のノード名 | 空(クラスター単位のアラーム) |
| cluster_name | 任意 | クラスター名 | cluster_id を使用 |
| alarm_severity | 任意 | アラームの重大度 | N/A |
出力形式
注記:以下のテンプレートに従って厳密に出力し、返してください。テンプレートの内容を分析または要約したり、一部を省略したり、テンプレートの構造を変更したりしないでください。出力はテンプレートと一致している必要があります。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<style>
body { font-family: "Microsoft YaHei", "PingFang SC", sans-serif; margin: 20px; background: #f5f7fa; color: #1d2129; }
.report { max-width: 960px; margin: 0 auto; background: #fff; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); overflow: hidden; }
.header { background: linear-gradient(135deg, #165dff, #0fc6c2); color: #fff; padding: 24px 32px; }
.header h1 { margin: 0; font-size: 22px; letter-spacing: 1px; }
.header .subtitle { margin-top: 4px; font-size: 13px; opacity: 0.85; }
.section { padding: 20px 32px; border-bottom: 1px solid #e5e6eb; }
.section:last-child { border-bottom: none; }
.section-title { font-size: 16px; font-weight: 600; color: #165dff; margin: 0 0 12px 0; padding-left: 10px; border-left: 3px solid #165dff; }
.info-grid { display: grid; grid-template-columns: 120px 1fr; row-gap: 8px; }
.info-key { color: #86909c; font-size: 14px; text-align: right; padding-right: 12px; }
.info-val { color: #1d2129; font-size: 14px; font-weight: 500; word-break: break-all; }
.conclusion-item { padding: 8px 12px; margin-bottom: 6px; background: #fff7e8; border-left: 3px solid #ff7d00; border-radius: 0 4px 4px 0; font-size: 14px; }
.conclusion-item.normal { background: #e8ffea; border-left-color: #00b42a; }
.locate-block { margin: 6px 0 6px 16px; padding: 10px 14px; background: #f7f8fa; border-radius: 4px; font-size: 13px; }
.locate-block .loc-row { display: flex; margin-bottom: 4px; }
.locate-block .loc-key { width: 80px; color: #86909c; flex-shrink: 0; }
.locate-block .loc-val { color: #1d2129; word-break: break-all; }
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th { background: #f2f3f5; color: #4e5969; font-weight: 600; text-align: left; padding: 10px 12px; border-bottom: 2px solid #e5e6eb; }
td { padding: 10px 12px; border-bottom: 1px solid #f2f3f5; vertical-align: top; }
tr:hover td { background: #f7f8fa; }
.sql-text { font-family: "Cascadia Code", "Fira Code", "Consolas", monospace; font-size: 12px; color: #4e5969; max-width: 500px; word-break: break-all; white-space: pre-wrap; }
.pct-bar { display: inline-block; height: 16px; border-radius: 2px; background: linear-gradient(90deg, #165dff, #0fc6c2); vertical-align: middle; }
.pct-val { margin-left: 6px; font-weight: 600; color: #165dff; }
.tag { display: inline-block; padding: 2px 8px; border-radius: 3px; font-size: 12px; font-weight: 500; }
.tag-warn { background: #fff7e8; color: #ff7d00; }
.tag-danger { background: #ffece8; color: #cb2634; }
.tag-info { background: #e8f3ff; color: #165dff; }
</style>
</head>
<body>
<div class="report">
<div class="header">
<h1>DWS 集群 CPU 诊断报告</h1>
<div class="subtitle">{region_id} | {resource_name}</div>
</div>
<div class="section">
<div class="section-title">基本信息</div>
<div class="info-grid">
<span class="info-key">所属服务</span><span class="info-val">DWS</span>
<span class="info-key">所属区域</span><span class="info-val">{region_id}</span>
<span class="info-key">集群名称</span><span class="info-val">{resource_name}</span>
<span class="info-key">集群ID</span><span class="info-val">{resource_id}</span>
<span class="info-key">TOP节点</span><span class="info-val">{node_name}</span>
</div>
</div>
<div class="section">
<div class="section-title">诊断结论</div>
{diagnosis_summary}
</div>
<div class="section">
<div class="section-title">CPU贡献 Top3 语句</div>
<table>
<tr><th style="width:40px">#</th><th style="width:180px">QueryID</th><th style="width:80px">用户</th><th style="width:80px">CPU占比</th><th style="width:160px">时间</th><th>SQL</th></tr>
<tr><td>1</td><td>{query_id}</td><td>{username}</td><td>{pct}%</td><td>{start_time_beijing}</td><td class="sql-text">{query_text}</td></tr>
<tr><td>2</td><td>{query_id}</td><td>{username}</td><td>{pct}%</td><td>{start_time_beijing}</td><td class="sql-text">{query_text}</td></tr>
<tr><td>3</td><td>{query_id}</td><td>{username}</td><td>{pct}%</td><td>{start_time_beijing}</td><td class="sql-text">{query_text}</td></tr>
</table>
</div>
<div class="section">
<div class="section-title">CPU贡献 Top3 用户</div>
<table>
<tr><th style="width:40px">#</th><th>用户名</th><th style="width:260px">CPU占比</th></tr>
<tr><td>1</td><td>{user1}</td><td><span class="pct-bar" style="width:{bar1}px"></span><span class="pct-val">{pct1}%</span></td></tr>
<tr><td>2</td><td>{user2}</td><td><span class="pct-bar" style="width:{bar2}px"></span><span class="pct-val">{pct2}%</span></td></tr>
<tr><td>3</td><td>{user3}</td><td><span class="pct-bar" style="width:{bar3}px"></span><span class="pct-val">{pct3}%</span></td></tr>
</table>
</div>
<div class="section">
<div class="section-title">CPU贡献 Top3 进程(不含gaussdb主进程)</div>
<table>
<tr><th style="width:40px">#</th><th>进程名</th><th style="width:260px">CPU占比</th></tr>
<tr><td>1</td><td>{process1}</td><td><span class="pct-bar" style="width:{bar1}px"></span><span class="pct-val">{pct1}%</span></td></tr>
<tr><td>2</td><td>{process2}</td><td><span class="pct-bar" style="width:{bar2}px"></span><span class="pct-val">{pct2}%</span></td></tr>
<tr><td>3</td><td>{process3}</td><td><span class="pct-bar" style="width:{bar3}px"></span><span class="pct-val">{pct3}%</span></td></tr>
</table>
</div>
</div>
</body>
</html>
diagnosis_summary の入力ルール:
- すべてのメトリクスが正常な場合 →
<div class="conclusion-item normal">診断暂未发现异常</div>を出力します - 異常がある場合は、異常ごとに
<div class="conclusion-item">を1つ出力します。内容の形式は<anomaly_type>: <factual_description>です - 特定の SQL が特定された場合は、異常項目の div の後に場所を示すサブブロックを追加します:
<div class="conclusion-item"><anomaly_type>: <factual_description></div> <div class="locate-block"> <div class="loc-row"><span class="loc-key">SQL摘要</span><span class="loc-val">{specific_sql} (max 50 characters)</span></div> <div class="loc-row"><span class="loc-key">QueryID</span><span class="loc-val">{query_id}</span></div> <div class="loc-row"><span class="loc-key">用户名</span><span class="loc-val">{username}</span></div> <div class="loc-row"><span class="loc-key">启动时间</span><span class="loc-val">{start_time_beijing}</span></div> </div> - 高い同時実行数と単一のステートメントは、それぞれ独立した異常項目として出力できます
- 読みやすさのため、異常項目にタグを付けることができます:システム側の原因には
<span class="tag tag-warn">系统</span>、顧客側の原因には<span class="tag tag-danger">客户侧</span>、高い同時実行数には<span class="tag tag-info">高并发</span>を使用します
上位 3 件のステートメントの入力ルール:
- データソース:cpu_io_diagnose_detail の上位 3 件のステートメントを cpu_rate の降順で並べます
- cpu_rate はすでにインスタンス単位の割合です(例:76.5% は、このクエリがそのインスタンスの CPU を 76.5% 使用していることを意味します)。cpu_rate の値をそのまま CPU 比率として使用し、グローバル合計またはノード合計で割って再計算しないでください
- cpu_io_diagnose_detail の各行は、1 つのインスタンスでの 1 回のクエリ実行を表します。上位 3 件を並べ替える際は、各行を個別に扱ってください
- QueryID:query_id フィールドから取得します。類似する SQL が複数ある場合は、件数の注記を付けてカンマ区切りにします(例:「73183494456652581等4条」)
- Username:username フィールドから取得します
- 時刻:duration_ms がある場合は、ctime - duration_ms を北京時間に変換し、列ヘッダーを「起動時間」とします。duration_ms がない場合は、ctime を北京時間に変換し、列ヘッダーを「収集時間」とします
- CPU 比率:cpu_rate フィールドの値をそのまま使用します(すでに割合です)。小数第 1 位まで表示します(例:76.5%)
- SQL:query フィールドから取得し、最大 1024 文字まで表示します。超過する場合は「...」で省略します
- gaussdb のメインプロセスは独立したステートメントとして記載しません。その CPU オーバーヘッドは、対応する根本原因の説明に含めます
- ステートメントデータがない場合(例:cpu_io_diagnose_detail が空の場合)、テーブルに「无法获取」と入力します
上位 3 件のユーザーの入力ルール:
- データソース:cpu_io_diagnose_detail の username ごとに集計した cpu_rate
- ここでの username は データベースユーザー であり、OS ユーザーではありません。command_cpu_usage の username フィールドは使用しないでください
- state=active のデータベースユーザーのみを集計します
- 比率 = ユーザーの cpu_rate 合計 / すべてのユーザーの cpu_rate 合計 × 100%
- データポイントが 3 件未満の場合は、実際の件数を列挙します
- pct-bar の幅は次の式で計算します:
width = Math.round(ratio / max_ratio * 200)。max_ratio は最上位ユーザーの比率です 上位 3 プロセスの入力ルール: - データソース:command_cpu_usage の command ごとに集計した cpu_rate
- command_cpu_usage の username フィールドは OS ユーザーを示します。cpu_io_diagnose_detail のデータベースユーザーとは異なるため、混同しないでください
- Gaussdb メインプロセスの除外:
commandがgaussdb-dnまたはgaussdb-cnの行を除外します(これらの CPU 使用率は SQL 文と根本原因に割り当てられます)。gaussdb(フェンス化された UDF のマスタープロセス)は除外しないでください。これはサブプロセスであり、上位 3 プロセスに含める必要があります - 残りのプロセスを cpu_rate の降順で並べ、上位 3 件を取得します
- 比率 = プロセスの cpu_rate 合計 / メインプロセス以外すべての cpu_rate 合計 × 100%
- プロセスの表示名:
commandフィールドの値をそのまま使用します(例:gaussdb、python3、java、sh、cm_agent、gs_gtm)。argsが異なる同じ command の複数のエントリは、同じ command 名の下に集計します - node_process_cpu_top20 が null で、command_cpu_usage も空の場合は、テーブルに「无法获取」と入力します
- pct-bar の幅の計算方法は「上位 3 ユーザー」と同じです
一般的な入力ルール:クラスター名には cluster_name を優先して使用し、空の場合は cluster_id を使用します。node_name が空の場合は「集群级告警」と入力します。gaussdb のメインプロセス(command が gaussdb-dn または gaussdb-cn)の CPU 使用率は、対応する根本原因の説明に含めます。gaussdb のフェンス化された UDF(command が gaussdb)はメインプロセスではなく、上位 3 プロセスに表示します。類似する SQL が複数ある場合は「同種のxxxクエリN件」と説明します。すべての時刻は北京時間にします。文の要約が 50 文字を超える場合は「...」を付けて切り詰めます。ブラウザーで直接レンダリングできる完全な HTML ドキュメントを出力します。SQL テキスト内の <、>、& は、それぞれ <、>、& にエスケープします。
ベストプラクティス
- タイムスタンプの処理:first_alarm_time はすでにミリ秒単位のタイムスタンプです。ツールのパラメーターにはそのまま使用してください。いったん時刻文字列に変換してからタイムスタンプに戻さないでください(8 時間のずれを防ぐため)
- ツールの選択:KooCLI と MCP から選択し、KooCLI を優先します。一度選択したら、その方法を最後まで使用してください
- ページネーション付きクエリ:すべてのツール呼び出しで一律に limit=200 を使用してページネーションし、返された件数が 200 未満になるまで続けてから、すべてのページのデータを統合します。cpu_io_diagnose_detail はデータ量が最も多いため、ページネーションが必要です
- レポート時刻:すべてのタイムスタンプを北京時間(UTC+8)に変換する必要があります。次のコマンドを使用できます:
python -c "from datetime import datetime,timezone,timedelta; print(datetime.fromtimestamp({ms}/1000,tz=timezone(timedelta(hours=8))).strftime('%Y-%m-%d %H:%M:%S'))" - SQL の表示:上位 3 件の文では、具体的な SQL を最大 1024 文字まで表示します。超える場合は「...」を付けて切り詰めます。diagnosis_summary の SQL 要約は最大 50 文字です
- ノードフィルタリングの最適化:ステップ 1 で CpuStat を解析する際、ノードごとに CPU 使用率の最大値と平均値をそれぞれ計算します。クラスターのノード数が 6 を超える場合は、上位 3 ノードのみを対象とします。上位ノードの最大値と平均値の差が 20% 未満の場合は、以降のステップでは上位 3 ノードのみを分析し、それ以外の場合は CPU 使用率が高いすべてのノードを分析します
参考資料
| ドキュメント | 説明 |
|---|---|
| CLI インストールガイド | KooCLI のインストールと設定 |
| MCP インストールガイド | DWS Autopilot MCP Server のインストールと設定 |
| IAM ポリシー | 必要な権限とポリシー JSON |
| メトリクスリファレンス | メトリクスのキー項目とクエリの違い |
メモ
- セキュリティ:会話やコマンドで AK/SK の値を絶対に公開しないでください。会話内でユーザーに AK/SK を直接入力するよう求めないでください。
- 時刻プロトコル:from_ts/to_ts にはミリ秒単位のタイムスタンプを使用する必要があります。レポートには北京時間が表示されます。北京時間をタイムスタンプに変換する際は、タイムゾーンサフィックス +08:00 を付ける必要があります。タイムスタンプの値を頭の中で計算しないでください。既存のミリ秒単位のタイムスタンプを時刻文字列に変換してから、再びタイムスタンプに戻さないでください。
- 出力制約:「出力形式」セクションのテンプレートに従って、診断レポートのみを厳密に出力してください。テンプレートの構造を変更せず、どの部分も省略せず、修正提案を追加せず、SQL 最適化ステートメントを出力せず、絵文字を使用せず、独自の書式タグを使用しないでください。
- データの信頼性:診断の結論はすべて、実際のツールの戻り値に基づいている必要があります。ツールの戻り値が空の場合、または呼び出しに失敗した場合は、「无法获取」と記載してください。値を捏造することは禁止されています。
- 既知の制限事項:hcloud は --order_by および --sort_by パラメーターをサポートしていません。クエリ後にローカルで ctime の降順に並べ替えてください。cpu_io_diagnose_detail は host_id によるフィルタリングをサポートしていません。クラスター全体をクエリしてからローカルでフィルタリングしてください。cpu_io_diagnose_detail はフラットな行構造(1 行につき 1 件のクエリ)を返し、ネストされた active_queries 配列は返しません。node_process_cpu_top20 は null を返す場合があります。command_cpu_usage の
commandフィールドは、gaussdb-dn/gaussdb-cn(メインプロセス、Top 3 の対象外)とgaussdb(フェンス付き UDF、対象に含む)を区別します。