mcpField
M
mcp-developer-analysis

mcp-developer-analysis

github.com/materializeinc数据与数据库3289 次安装今天更新
代码仓库

关于 mcp-developer-analysis

此技能通过 MCP Developer 端点分析 Materialize 环境,指导目录发现、性能与资源检查,并生成含优化建议的结构化报告。

主要功能

  1. 01系统目录发现
  2. 02新鲜度与水合状态检查
  3. 03内存与 CPU 分析
  4. 04工作节点偏斜调查
  5. 05结构化发现与建议

适用场景

  1. 01盘点已部署的 Materialize 对象
  2. 02调查延迟或水合问题
  3. 03检查副本资源使用情况
  4. 04定位工作节点间的性能失衡

MCP 相关

使用 Materialize MCP Developer 端点提供的只读查询工具检查系统目录,并在工具可用时查询指定集群上的用户对象。

安装

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

$npx skills add https://github.com/materializeinc/agent-skills --skill mcp-developer-analysis

安装后在 Claude Code 中输入/mcp-developer-analysis确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

mcp-client-connect.md
README.md
references/
queries.md
report-template.md

详细介绍

Materialize 开发者分析

通过 MCP Developer 端点分析 Materialize 环境,并生成一份包含健康状态、性能发现和优化建议的结构化报告。假设 Materialize 版本为 v26.24 或更高。

开发者端点提供两个只读工具:

  • query_system_catalog — 对系统目录表(mz_*、pg_catalog、information_schema)执行 SELECT/SHOW/EXPLAIN。不接受 cluster 参数;即使传入了参数,也会被静默忽略,而非报错。当 auto_route_catalog_queries 开启(默认设置)时,目录查询会自动路由到目录服务集群(mz_catalog_server);路由器无法在该集群上处理的查询——尤其是所有 mz_introspection 关系的查询——则会在会话的默认集群上执行(如果设置了角色的 cluster 默认值,则使用该值;否则使用系统默认值 quickstart,除非操作员已修改)。大多数目录查询都应使用此工具。
  • query(在 Materialize v26.30 中添加)— 对角色有权访问的任何对象执行 SELECT/SHOW/EXPLAIN,并在必需的 cluster 参数指定的集群上运行(从 v26.33 起,还可选填 cluster_replica)。执行 EXPLAIN ANALYZE(必须在 MV/索引所在的集群上运行)以及直接读取用户数据时,必须使用此工具。如果操作员禁用了 enable_mcp_developer_query_tool,此工具可能会被隐藏。

将 MCP 客户端连接到 materialize-developer

如果用户询问如何将 MCP 客户端(Claude Code、Cursor、VS Code、Zed、Continue、Windsurf、Claude Desktop)配置、连接或设置为与 materialize-developer 服务通信——包括如何控制连接所用的用户或角色,或如何在不同身份之间切换——请参阅 mcp-client-connect.md。其中介绍了 Emulator、Materialize Cloud 和自管理部署,并提供了各客户端的代码片段、身份验证模式和验证方法。

本 SKILL.md 的其余部分介绍连接后如何分析环境。

发现表和列

不要猜测列名。 系统目录关系包含表、视图、物化视图和源,因此没有单个 SHOW TABLES 或 SHOW VIEWS 能列出所有对象;请使用 SHOW OBJECTS FROM <schema>。mz_internal 中的本体视图描述了目录;请使用这些视图来发现正确的表、列、联接路径和 ID 类型:

表说明
mz_internal.mz_ontology_entity_types现有的目录实体,以及它们映射到的 mz_* 表。
mz_internal.mz_ontology_link_types实体之间的关系(外键、指标等)。
mz_internal.mz_ontology_properties每个实体的列名、类型和说明。
mz_internal.mz_ontology_semantic_types类型化的 ID 域(CatalogItemId、ReplicaId 等)。

示例查询:

-- Find the right table for an entity
SELECT name, relation, description
FROM mz_internal.mz_ontology_entity_types
WHERE name LIKE '%source%'

-- Find join paths between entities
SELECT name, source_entity, target_entity, properties, description
FROM mz_internal.mz_ontology_link_types
WHERE source_entity = 'source' OR target_entity = 'source'

-- Find columns for a table
SELECT column_name, semantic_type, description
FROM mz_internal.mz_ontology_properties
WHERE entity_type = 'source_status'

查询前,请使用 SHOW COLUMNS FROM <schema>.<table> 验证列名。

重要规则

服务自身的 initialize 说明中包含目录相关注意事项:例如 last_status_change_at 等列名、mz_cluster_replica_utilization 的副本到集群的 JOIN、本体视图,以及从 v26.40 起的 mz_introspection 路由和 ID 类型。大多数客户端都会转发这些说明;如果你的客户端不会,则可使用 SHOW COLUMNS 作为替代。

mz_introspection 关系需要使用 query 工具

每个 mz_introspection 关系(包括 mz_dataflow_arrangement_sizes)都限定于集群,而 query_system_catalog 无法指定集群,因此通过该工具读取时会落到会话的默认集群:如果该集群恰好有一个副本,你会得到该副本的数据,或者得到空结果,且不会报错;如果有多个副本,读取会失败并提示 log source reads must target a replica;如果没有副本,则会提示 has no replicas available to service request。请使用带 cluster 参数的 query 读取这些关系;对于有多个副本的集群,还要使用 cluster_replica(从 v26.33 起支持,不计费的副本也算),这正是第一个错误要求的操作;第二个错误则无法通过此方式解决。 v26.40 之前的服务器会在其 initialize 指令中要求不要查询 mz_dataflow_arrangement_sizes;这条规则早于 query 工具,此处说明优先于该规则。相关查询、通往目录的联接路径及注意事项,见 references/queries.md 中的 Arrangement Sizes。如果没有 query 工具,请改用下面“内存和资源消耗”部分中的关系。

工作流概览

  1. 连接 — 确认 MCP Developer 工具可用
  2. 发现 — 使用本体和目录查询,盘点所有已部署对象
  3. 分析 — 评估性能指标:新鲜度、水合状态、内存、利用率
  4. 报告 — 生成包含发现和建议的结构化 Markdown 报告

步骤 1:验证 MCP 连接

确认你可以使用 query_system_catalog 工具。运行一个快速测试:

query_system_catalog: SELECT mz_version() FROM mz_catalog.mz_databases LIMIT 1

query_system_catalog 会拒绝不引用系统目录表的 SELECT,因此单独执行 SELECT mz_version() 会失败,并提示 Query must reference at least one system catalog table,这看起来像是连接故障。

检查客户端提供的工具中是否有 query 工具。使用该工具,你还可以对命名集群上的用户对象运行 EXPLAIN ANALYZE 和查询;如果没有该工具(因为操作员禁用了它,或使用的是 v26.30 之前的版本),则对所有适用的操作使用 query_system_catalog。

如果 query_system_catalog 失败,请检查:

  • MCP 服务已在客户端的 MCP 配置中注册(不同客户端使用的文件和键各不相同,详见 mcp-client-connect.md)
  • 环境中已启用 enable_mcp_developer 功能标志
  • 身份验证凭据有效
运行查询

每次调用中,两种工具都只接受一条只读语句,不支持 SET,且末尾不能有分号(可以有一个;两个语句会被拒绝)。

结果以不带列名的裸行数组形式返回,所有 AS 别名都会被丢弃,因此请按位置映射列,并让 SELECT 列表保持简短,且按你打算读取的顺序排列。数字会以字符串形式返回,布尔值会以 JSON true/false 形式返回,NULL 会以 null 形式返回;timestamp 和 timestamptz 值会以毫秒级 Unix 纪元时间戳字符串形式返回(1787687415336.000),需要可读时间时,请将它们转换为 text。如果对象不在当前会话所在的数据库中(SHOW database),请使用数据库名称限定对象名,否则语句会因 unknown schema 而失败。响应有大小上限(默认 1 MB),请求也有超时时限(默认 60 秒);两者都可由运维人员配置,超限时都会报错。使用 LIMIT 可以让目录枚举结果不超过上限;它只会减少对单个索引关系的简单读取所需的工作量,不会减少连接查询的工作量。超时会释放此次调用,但查询有时仍会继续运行,因此不要原样重试超时的语句。

query_system_catalog 通过遍历 FROM 子句中的表引用来检查允许列表,因此不含此类引用的语句完全不会经过检查:SHOW TABLES、SHOW COLUMNS、SHOW CREATE 各种形式以及对象级 EXPLAIN ANALYZE 都可以通过检查并指定用户对象(这也是后者会返回空结果的原因,见“Worker Skew”)。仅在缺少 query 时将其作为后备方案;查询用户对象时请使用 query。

过滤系统架构时,务必始终排除:mz_catalog、mz_internal、pg_catalog、information_schema 和 mz_introspection。SHOW SCHEMAS 还会列出 mz_catalog_unstable 和 mz_unsafe,其中不包含任何关系。

步骤 2:发现 — 清点环境

运行发现查询,了解已部署的内容。完整查询集请参见 references/queries.md。发现阶段包括:

环境概览
  • Materialize 版本
  • 集群和副本——名称、managed、副本数量和规格。请从 mz_clusters 开始并 LEFT JOIN 副本,否则没有副本的集群会从清单中消失。非托管集群的 size 和 replication_factor 为 NULL;未计费的支持副本列在 mz_internal.mz_internal_cluster_replicas 中,与其他副本一样计数。
  • 正在使用的架构
已部署对象清单
  • 源:类型(Kafka、Postgres、MySQL、Webhook 等)、集群分配、状态。mz_sources 还会为每个子源和 progress 集合各包含一行,因此统计源数量前,请先筛选 type NOT IN ('subsource', 'progress')。
  • 物化视图:集群分配、索引、依赖关系
  • 视图:(非物化视图)及其使用模式
  • Sink:类型、目标位置、集群分配
  • 索引:所属对象、集群分配
  • 连接:已配置的外部系统连接
对象定义

使用 references/queries.md 获取物化视图、视图、索引和源的 SQL 定义。这对优化分析至关重要——SQL 定义会告诉你内容的计算方式:

  • 连接模式和连接顺序
  • 筛选谓词(或缺失的筛选谓词——缺少时间筛选是常见问题)
  • 聚合策略
  • 物化视图是否重复了本可共享的逻辑

步骤 3:分析 — 性能和资源指标

新鲜度(延迟分析)

查询 mz_internal.mz_materialization_lag 获取每个对象的延迟。其 local_lag 和 global_lag 列是普通的 interval,可直接比较和排序;slowest_global_input_id 则指出导致对象落后的输入。两种延迟都以输入的前沿为基准,而非墙上时钟:如果源已暂停,管道会显示零延迟,但数据可能变得任意陈旧,因此还要将 mz_frontiers.write_frontier 与 now() 比较(参见 Write Frontiers 查询)。

write_frontier 不在此关系中,而是在 mz_internal.mz_frontiers 中,类型为 mz_timestamp。将其转换为 timestamptz 可获得易读的时间,转换为 text(再转为 bigint)可获得原始数值,不能直接转换为 bigint。查询语句见 references/queries.md。

水合状态

查询 mz_internal.mz_hydration_statuses,检查所有数据流是否已水合。初次启动后仍未水合的对象可能表示资源压力或配置问题。对副本列使用 LEFT JOIN:没有可供水合的副本时,replica_id 为 NULL;内连接会隐藏这些对象。

内存和资源消耗
  • 使用 mz_internal.mz_cluster_replica_utilization 获取每个副本进程的内存/CPU 百分比
  • 使用 mz_internal.mz_cluster_replica_metrics 获取原始内存指标;每个(副本、进程)对应一行
  • 使用 mz_internal.mz_index_advice 确定哪些 MV/索引可以优化
Worker 偏斜(各 worker 之间的 CPU 不均衡)

使用 WITH SKEW 查找某个 worker 承担了不成比例的 CPU/内存工作的算子。

请通过 query 工具运行这些命令,而不是 query_system_catalog: EXPLAIN ANALYZE 会在你通过 cluster 参数指定的集群上执行;对于对象级命令,该集群必须是 MV/索引所在的集群。选错集群不一定会报错:在另一个单副本集群上,或默认集群只有一个副本时通过 query_system_catalog 运行,对象级命令会返回空结果,看起来像是“没有偏斜”;有多个副本时,读取会失败并提示 log source reads must target a replica;没有副本时,则会提示 has no replicas available to service request。不使用 query,本节内容就无法实际操作。

集群级别(在要检查的集群上运行):

EXPLAIN ANALYZE CLUSTER CPU WITH SKEW

对象级别(对 MV 及其索引都运行):

EXPLAIN ANALYZE CPU WITH SKEW FOR MATERIALIZED VIEW <schema>.<mv_name>
EXPLAIN ANALYZE CPU WITH SKEW FOR INDEX <schema>.<index_name>

如果存在偏斜:确定发生偏斜的算子(通常是 TopK/window/agg/join/distinct),然后检查定义(SHOW CREATE ...),并建议具体的 SQL 更改(移除/调整提示、重构键/分区,或重写 MV)。

索引建议

查询 Materialize 内置顾问 mz_internal.mz_index_advice。它会准确给出六种建议:keep、drop unless queried directly、convert to a view、convert to a view with an index、convert to materialized view、add index。筛选部分建议会悄无声息地漏掉实际建议;各项含义见 references/queries.md。

成本分析(可选)

使用 references/queries.md 中的 Cost Analysis 查询(按副本定价)。

撰写建议时,始终量化 credits 的影响(credits 是 Cloud 的计费单位;在自管理部署中,随附规格使用 Cloud 的数值,而操作员自定义的规格使用操作员设定的数值,默认为 0,因此最多只能将其作为相对权重呈现)。

对象依赖关系

查询 mz_internal.mz_object_dependencies 以了解依赖关系图。

第 4 步:报告 — 生成分析结果

按照 references/report-template.md 生成结构化 Markdown 报告,包含执行摘要、集群拓扑、已部署对象、性能分析(新鲜度、水合状态、资源利用率、worker 偏斜、源和接收器健康状况)、成本分析、索引建议、SQL 级别分析,以及附有具体 SQL 的编号建议。

集群拓扑表取自 references/queries.md 中的 Cluster Topology 查询,以及其中 Current Compute Cost per Cluster 的 credits 列。

撰写建议

**始终包含具体的 SQL 命令。**例如:

正确:

建议: 将 my_schema.unused_mv 去物化以节省内存。

SHOW CREATE MATERIALIZED VIEW my_schema.unused_mv
DROP MATERIALIZED VIEW my_schema.unused_mv
CREATE VIEW my_schema.unused_mv AS <definition>

错误:

建议: 考虑将 my_schema.unused_mv 去物化。

故障排查手册

结尾务必提供用于修复问题的具体 SQL 命令,且未经用户同意,绝不要执行这些命令:扩容或添加副本会产生费用,删除或修改对象会丢失状态。下面的所有修复方案都是 DDL,两种工具都会拒绝执行,因此应将命令交给用户。

“为什么我的物化视图已过时?”

诊断步骤:

  1. 首先检查 MV 所在集群是否有副本:使用 mz_clusters LEFT JOIN mz_cluster_replicas(Clusters and Replicas 查询),不要看 replication_factor,因为非托管集群中的该值为 NULL,且无法反映 未计费的副本。没有副本的集群不会运行任何内容,后续步骤也难以发挥作用。
  2. 检查 mz_internal.mz_hydration_statuses——MV 是否已完成水合,以及集群上的其他所有对象是否都已完成水合(Non-Hydrated Objects 查询,并限定在该集群内)?
  3. 检查 mz_internal.mz_cluster_replica_status_history 中是否有近期原因 为 oom-killed 的 offline 事件;这涵盖 cgroup OOM killer、堆限制器以及 lgalloc 溢出磁盘已满这几种情况(Replica Restarts 查询;模拟器不会记录原因,因此应根据 offline 次数判断):OOM 循环中,当前状态通常会显示 online,利用率采样值也可能不高。大多数 OOM 发生在水合期间,因此当步骤 2 显示所有内容都已完成水合,且每个进程最新的历史记录行为 online 时,循环就结束了;水合完成后仍反复发生的终止属于稳态循环,只有调整规格或减少集群上的负载才能解决。
  4. 检查 mz_internal.mz_cluster_replica_utilization:memory_percent 接近 100 表示 RAM 已满,进一步增长的部分会进入交换空间(如果存在),表现为水合缓慢或延迟;heap_percent(RAM 加交换空间相对于限制的占比)不断上升,而 memory_percent 保持不变,说明正在使用交换空间;接近 100 时,下一次峰值就会导致副本被终止。无论哪种情况:都可以扩容、迁移 MV,或减少集群承载的内容(见下方修复方案和步骤 7)。
  5. 检查 mz_internal.mz_source_statuses——上游数据源是否有错误?
  6. 检查 mz_internal.mz_materialization_lag,查看 MV 的延迟(参见“新鲜度”)
  7. 如果 query 工具可用,请在 MV 所在集群上运行 EXPLAIN ANALYZE MEMORY FOR MATERIALIZED VIEW <schema>.<mv>,查看每个运算符的内存使用情况,并找出开销较大的结构(大型整理结构、没有索引的连接、缺少时间过滤条件)。

常见修复方案:

如果 MV 所在集群没有副本:

ALTER CLUSTER <cluster_name> SET (REPLICATION FACTOR 1)
-- Unmanaged cluster: add a replica directly
CREATE CLUSTER REPLICA <cluster_name>.r1 (SIZE = '<size>')

如果集群过载(内存/CPU 使用率高):

-- Option A: Scale up the cluster (unmanaged: DROP and CREATE its replicas
-- at the bigger size instead)
ALTER CLUSTER <cluster_name> SET (SIZE = '<next_size_up>')
-- Option B: Move the MV to a different cluster
SHOW CREATE MATERIALIZED VIEW <schema>.<mv_name>
DROP MATERIALIZED VIEW <schema>.<mv_name>
CREATE MATERIALIZED VIEW <schema>.<mv_name> IN CLUSTER <new_cluster> AS <definition>

如果上游数据源未运行:

SELECT name, status, error, last_status_change_at
FROM mz_internal.mz_source_statuses
WHERE status != 'running'

并非所有非 running 状态都表示故障,只有 stalled 状态会带有 error;下文“我的数据源是否正常?”会列出每种状态的含义。请先解决上游数据源的问题。MV 的新鲜度取决于数据源的健康状况。

“为什么我的集群内存不足?”

诊断步骤:

  1. 查看 mz_internal.mz_cluster_replica_utilization 中的内存百分比,以及 mz_cluster_replica_status_history 中的 oom-killed 事件(副本重启)
  2. 查看 mz_internal.mz_index_advice,找出可以取消物化的 MV
  3. 检查 MV 定义中是否缺少时间过滤器
  4. 检查是否存在冗余索引
  5. 如果有 query 工具可用,在可疑对象所在的集群上运行 EXPLAIN ANALYZE MEMORY FOR MATERIALIZED VIEW <schema>.<mv>(或 FOR INDEX <name>),查看哪些运算符占用的内存最多——这是确认哪种编排方式造成问题的最直接方法。

常见修复方法:

取消不需要物化的 MV:

SELECT o.name, o.type, sc.name AS schema_name, ia.hint, ia.details
FROM mz_internal.mz_index_advice ia
JOIN mz_catalog.mz_objects o ON ia.object_id = o.id
JOIN mz_catalog.mz_schemas sc ON o.schema_id = sc.id
WHERE ia.hint = 'convert to a view'

convert to a view with an index 和 convert to materialized view 也是内存建议,但对应的修复方式不同,因此在执行此操作前,请阅读完整的建议集(references/queries.md 中的 Index Advice 查询)。

-- For each candidate:
SHOW CREATE MATERIALIZED VIEW <schema>.<mv_name>
DROP MATERIALIZED VIEW <schema>.<mv_name>
CREATE VIEW <schema>.<mv_name> AS <definition>

删除未使用的索引:

SELECT o.name, o.type, sc.name AS schema_name, ia.hint, ia.details
FROM mz_internal.mz_index_advice ia
JOIN mz_catalog.mz_objects o ON ia.object_id = o.id
JOIN mz_catalog.mz_schemas sc ON o.schema_id = sc.id
WHERE ia.hint = 'drop unless queried directly'
-- Verify with the user before dropping
DROP INDEX <schema>.<index_name>

扩容集群(非托管集群:改为 DROP 并以更大的规格 CREATE 其副本):

ALTER CLUSTER <cluster_name> SET (SIZE = '<next_size_up>')
“我的源运行正常吗?/ 我的源是否已完成快照?”

诊断步骤:

  1. 查看 mz_internal.mz_source_statuses 中的源错误
  2. 查看 mz_internal.mz_source_statistics 中的摄取进度
  3. 查看 mz_internal.mz_materialization_lag 中的端到端延迟

常见修复方法:

如果源未运行:

SELECT name, status, error
FROM mz_internal.mz_source_statuses
WHERE status != 'running'

状态包括 created(尚未记录状态)、starting、running、paused、stalled 或 dropped;文档还列出了 failed,但代码不会产生此状态。只有 stalled 状态会附带 error。Webhook 和 progress 行的状态始终为 running。created 和 starting 是正常的临时状态;paused 表示源所在的集群没有副本,再怎么等待也无法解决:

-- paused: give the source's cluster a replica
ALTER CLUSTER <cluster_name> SET (REPLICATION FACTOR 1)
-- unmanaged cluster: CREATE CLUSTER REPLICA <cluster_name>.r1 (SIZE = '<size>')
-- stalled/failed on bad credentials:
ALTER SECRET <secret_name> AS '<new_value>'

如果 snapshot_committed 为 false,说明源仍在加载初始快照。对于大型源,这是正常现象——请等待加载完成;源或副本启动后的约两分钟内,即使计数器为零,它也会显示 false。如果源完全没有 mz_source_statistics 行,说明它从未运行过,因此请检查其状态以及所在集群是否有任何副本,而不是继续等待;已暂停的源会保留过时的行,因此请先查看 status。

“我的环境运行状况如何?”

按顺序运行以下检查:

  1. mz_internal.mz_cluster_replica_statuses — 所有用户集群的副本是否都已就绪,且 mz_cluster_replica_status_history 中近期没有 oom-killed 事件?
  2. mz_internal.mz_source_statuses — 所有源是否都在运行?
  3. mz_internal.mz_sink_statuses — 所有 Sink 是否都在运行?
  4. mz_internal.mz_cluster_replica_utilization — 是否存在资源压力?
“我可以优化哪些方面来节省成本?”
  1. 查看 mz_internal.mz_index_advice,找出优化候选项
  2. 检查集群利用率——集群是否配置过度?
  3. 查看 mz_catalog.mz_cluster_replica_sizes 中的信用点费率

备注

  • 访问权限由 RBAC 管理,因此你只能看到凭据有权访问的数据。目录不受同样的限制:即使角色没有对象授权,仍可读取完整的对象清单、每个视图和 MV 的 definition,以及全部 mz_index_advice。启用 RBAC 时,query 和所有不会自动路由的读取操作还需要在其运行所在的集群上拥有 USAGE 权限(mz_catalog_server 会向 PUBLIC 授予该权限)。是否进行 RBAC 检查取决于部署方式及其配置;运行 SHOW enable_rbac_checks 和 SHOW enable_session_rbac_checks 即可查看(任一项为 on 都会启用检查)。
  • 新鲜度数值是某一时刻的快照。请重新运行以检查延迟是否稳定或正在增长。

评论

支持 Markdown