mcpField
H
huawei-cloud-dws-cpu-diag

huawei-cloud-dws-cpu-diag

github.com/huaweicloud云与 DevOps59178 次安装2 天前更新
代码仓库

关于 huawei-cloud-dws-cpu-diag

用于诊断 Huawei Cloud DWS 集群 CPU 使用率过高问题的技能,面向处理集群告警和负载异常的运维人员。它采集监控指标、分析可能原因,并生成标准化诊断报告。

主要功能

  1. 01采集集群 CPU 及相关指标
  2. 02分析节点负载和业务并发
  3. 03检查查询与进程 CPU 数据
  4. 04使用 KooCLI,必要时回退到 MCP
  5. 05生成标准化诊断报告

适用场景

  1. 01调查 DWS 集群 CPU 告警
  2. 02定位集群负载异常原因
  3. 03响应用户发起的 CPU 诊断请求

MCP 相关

技能可调用 dws_autopilot MCP 服务查询集群、主机和指标;当 KooCLI 不可用时将其作为替代方式。

安装

复制下面的命令,在终端中运行。

$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.md
iam-policies.md
metric-reference.md

详细介绍

华为云 DWS CPU 高使用率诊断技能

概述

此技能专用于 DWS 集群 CPU 高使用率的根因诊断。当集群触发 CPU 使用率过高告警时,它会自动收集指标数据、分析根因(客户侧/系统侧),并输出标准化诊断报告。

架构:KooCLI (hcloud) → DWS Autopilot API → 集群监控指标;MCP Server (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 Server 配置(备用)
  • KooCLI 不可用时,使用 MCP Server 作为替代方案
  • 请参阅 MCP 安装指南
3. 身份验证配置
  • 有效的华为云凭证(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 Server 之间进行选择,并优先使用 KooCLI。步骤 0 检查 hcloud 是否可用:

  • hcloud 可用(版本 >= 3.2.0)→ 后续步骤使用 KooCLI 命令行调用
  • hcloud 不可用(未安装或版本 < 3.2.0)→ 后续步骤使用 MCP Server 工具调用

备用与终止策略:

  • 选择 hcloud 后,如果首次调用返回 NETWORK_ERROR(连接超时、网络不可达等),则自动切换到 MCP Server,并在后续所有步骤中使用 MCP 模式
  • 如果 hcloud 返回 NETWORK_ERROR,且 MCP Server 也不可用(未配置或返回身份验证/连接错误),则终止此技能并输出:KooCLI network unavailable and MCP Server connection failed. Please check KooCLI network configuration or DWS Autopilot MCP Server configuration and retry
  • 选择 MCP Server 后,如果首次调用返回身份验证错误(例如 401 Unauthorized),则不要切换到 hcloud。直接终止此技能并输出:MCP Server authentication failed. Please check DWS Autopilot MCP Server authentication configuration and retry
  • 非 NETWORK_ERROR 的 hcloud 调用失败(例如参数错误、权限不足)不会触发备用切换;请遵循现有重试逻辑

选择工具后,除 NETWORK_ERROR 触发备用切换外,整个过程中都使用该工具,不要切换。如果调用失败,重试一次(最多 2 次)。如果仍然失败,则将该指标标记为“不可用”,并继续下一步。当所有指标查询都失败时,直接生成诊断报告。

参数映射
通用参数hcloud 参数MCP 参数
区域--cli-region(内置于 MCP 连接)
项目 ID--project_idproject_id
集群 ID--cluster_idcluster_id
指标名称--metric_namemetric_name
开始时间--fromfrom_ts
结束时间--toto_ts
分页偏移量--offsetoffset
分页限制--limitlimit
排序字段(不支持)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 服务配置
步骤 1:查询 CpuStat

调用指标查询,设置 metric_name="CpuStat",时间范围:from_ts=first_alarm_time - 1200000,to_ts=first_alarm_time。在 MCP 模式下,使用 limit=200 进行分页查询。

自动驾驶不可用的判定: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;部分节点 CPU 较高 → partial_nodes。

负载均衡判定:对于 TOP 节点,比较 CPU 最大值与平均值的差异。如果所有 TOP 节点均满足 |max - avg| / avg < 20%,则为“负载均衡”;后续步骤(步骤 4-5.5)仅需分析 TOP 3 个节点。否则为“负载不均衡”;后续步骤需分析所有高 CPU 节点。

输出:cpu_by_host、max_cpu_hosts(按平均值排序的 TOP 节点列表)、problem_host_id、problem_host_cpu_usage、cpu_scope、high_cpu_nodes、is_balanced、nodes_to_analyze(后续步骤要分析的节点列表)

步骤 2:获取主机名称

调用主机信息查询(MCP 模式下使用 limit=200 进行分页),构建 host_id → {host_name, ip} 映射表。仅查询步骤 1 输出的 nodes_to_analyze 中涉及的节点的主机信息。

输出:host_id_to_info_map、problem_host_ip、node_name

步骤 3:查询业务并发量

调用指标查询,设置 metric_name="business_concurrency"。在 MCP 模式下,使用 limit=200 进行分页查询,直到返回数量 < 200。

输出:max_concurrency、avg_concurrency、is_high_concurrency

步骤 4:查询 CPU 最高节点的诊断详情

调用指标查询,设置 metric_name="cpu_io_diagnose_detail"。不支持按 host_id 筛选;查询整个集群后,再根据步骤 1 输出的 nodes_to_analyze 进行筛选。MCP 模式必须使用 limit=200 进行分页查询(该指标的数据量最大,单页查询 800 条会超出 token 限制),直到返回数量 < 200,然后合并所有分页数据,再进行筛选。

解析:提取活跃查询、用户、持续时间和进程信息。ctime 是采集时间,而非 SQL 开始时间;当 duration_ms 存在时,SQL 开始时间 = ctime - duration_ms。仅统计 state=active 的用户。inst_name 包含 "cn" → CN 实例;包含 "dn" → DN 实例。

注意:cpu_io_diagnose_detail 返回的是扁平行结构(每行一条查询记录),而非嵌套的 active_queries 数组。关键字段: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

步骤 5:查询进程 CPU TOP 20

调用指标查询,设置 metric_name="node_process_cpu_top20"。在 MCP 模式下,使用 limit=200 进行分页查询。查询整个集群后,再根据步骤 1 输出的 nodes_to_analyze 进行筛选。注意:此指标可能返回 null;如果返回 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(围栏 UDF 子进程)、python3、java、sh、cm_agent、gs_gtm 等。args 字段包含完整的命令详情(例如,/DWS/manager/app/bin/gaussdb --datanode ...)。username 字段是操作系统用户(例如,Ruby、root),不是数据库用户。

Gaussdb 主进程定义:command 字段为 gaussdb-dn 或 gaussdb-cn → gaussdb 主进程(其 CPU 使用率归因于 SQL 语句和根因,不计入 Top 3 进程)。command 字段为 gaussdb(围栏 UDF 主进程)→ 不是主进程,计入 Top 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(围栏 UDF,不是 gaussdb-dn/gaussdb-cn)→ 子进程异常。

客户侧原因:高并发(多用户/单用户)、单条语句(CPU 占比 > 30%)、数据倾斜/计算倾斜。高并发和单条语句可能同时匹配。

系统原因:系统内部 SQL(VACUUM 等)、异常进程、SysCPU 高。

统计信息:计算以下三类 Top 3:

  1. Top 3 语句(来自 cpu_io_diagnose_detail):按 cpu_rate 降序排列(cpu_rate 已是实例级百分比,直接使用),输出 query_id、username、开始时间、CPU 占比、具体 SQL(最多 1024 个字符)。每行代表一个实例上的一条查询;不要通过除以全局总量重新计算占比。
  2. Top 3 数据库用户(来自 cpu_io_diagnose_detail):按 username 汇总 cpu_rate(仅统计 state=active),输出 username 和占比。此处的 username 是数据库用户,不是操作系统用户。占比 = 用户 cpu_rate 总和 / 所有用户 cpu_rate 总和 × 100%。
  3. Top 3 操作系统进程(来自 command_cpu_usage):按 command 汇总 cpu_rate,排除 gaussdb 主进程(command 为 gaussdb-dn 或 gaussdb-cn);其余进程按 cpu_rate 降序排列,取 Top 3。注意:gaussdb(围栏 UDF)不是主进程,应计入统计。command_cpu_usage 中的 username 字段是操作系统用户,与数据库用户不同;不要混淆。占比 = 进程 cpu_rate 总和 / 所有非主进程 cpu_rate 总和 × 100%。
步骤 7:生成诊断报告

按照“输出格式”部分中的模板生成 HTML 报告。生成报告后,将 HTML 文件保存到当前工作目录(工作区根文件夹),文件名为 dws_cpu_diagnosis_report_{timestamp}.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必填项目 IDN/A
cluster_id必填集群 IDN/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">,内容格式为:<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>

Top 3 语句填写规则:

  • 数据来源:cpu_io_diagnose_detail 中按 cpu_rate 降序排列的前 3 条语句
  • cpu_rate 已是实例级百分比(例如,76.5% 表示此查询在该实例上使用了 76.5% 的 CPU)。直接使用 cpu_rate 值作为 CPU 占比;不要除以全局总量或节点总量重新计算
  • cpu_io_diagnose_detail 中的每一行代表一个实例上的一次查询执行;排序选取前 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 为空),则在表格中填写“无法获取”

Top 3 用户填写规则:

  • 数据来源:按 username 聚合 cpu_io_diagnose_detail 中的 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 是排名第一的用户占比 Top 3 进程填充规则:
  • 数据来源:从 command_cpu_usage 中按命令聚合的 cpu_rate
  • command_cpu_usage 中的 username 字段表示 OS 用户,与 cpu_io_diagnose_detail 中的数据库用户不同;不要混淆两者
  • 排除 Gaussdb 主进程:排除 command 为 gaussdb-dn 或 gaussdb-cn 的行(它们的 CPU 使用率归入 SQL 语句和根因)。不要排除 gaussdb(fenced UDF 主进程)——它是子进程,应纳入 Top 3
  • 将其余进程按 cpu_rate 降序排列,取 Top 3
  • 占比 = 进程的 cpu_rate 总和 / 所有非主进程的 cpu_rate 总和 × 100%
  • 进程显示名称:直接使用 command 字段值(例如 gaussdb、python3、java、sh、cm_agent、gs_gtm)。同一 command 下的多个条目即使 args 不同,也会聚合到同一个命令名称下
  • 如果 node_process_cpu_top20 返回 null,且 command_cpu_usage 也为空,则在表格中填入“无法获取”
  • pct-bar 宽度的计算方式与 Top 3 用户相同

通用填充规则:集群名称优先使用 cluster_name;如果为空,则使用 cluster_id;node_name 为空时,填入“集群级告警”;Gaussdb 主进程(command 为 gaussdb-dn 或 gaussdb-cn)的 CPU 使用率合并到相应的根因描述中;Gaussdb fenced UDF(command 为 gaussdb)不是主进程,应出现在 Top 3 进程中;多条相似 SQL 描述为“N条同类xxx查询”;所有时间均使用北京时间;超过 50 个字符的语句摘要截断并添加 "...";输出为可直接在浏览器中呈现的完整 HTML 文档;SQL 文本中的 < > & 必须转义为 &lt; &gt; &amp;。

最佳实践

  1. 时间戳处理:first_alarm_time 已经是毫秒时间戳;直接将其用于工具参数。不要先转换为时间字符串,再转换回时间戳(以避免 8 小时偏差)
  2. 工具选择:在 KooCLI 和 MCP 之间选择,优先使用 KooCLI;一旦选定,就始终使用该方法
  3. 分页查询:所有工具调用统一使用 limit=200 分页,直到返回数量 < 200,然后合并所有分页数据。cpu_io_diagnose_detail 的数据量最大;必须分页
  4. 报告时间:所有时间戳都必须转换为北京时间(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'))"
  5. SQL 显示:Top 3 语句最多显示 1024 个字符的具体 SQL;超出时截断并添加 "...";diagnosis_summary 中的 SQL 摘要最多 50 个字符
  6. 节点筛选优化:在步骤 1 解析 CpuStat 时,分别计算每个节点的 CPU 使用率最大值和平均值;当集群节点数 > 6 时,仅关注 TOP 3 节点;如果 TOP 节点的最大值与平均值之差 < 20%,则后续步骤仅分析 TOP 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 返回扁平行结构(每行对应一条查询),而不是嵌套的 active_queries 数组;node_process_cpu_top20 可能返回 null;command_cpu_usage 的 command 字段用于区分 gaussdb-dn/gaussdb-cn(主进程,排除在 Top 3 之外)和 gaussdb(隔离的 UDF,纳入统计)

评论

支持 Markdown