别再让 AI 猜故障了:MySQL + Prometheus + Loki + Grafana 四件套接入 Agent 全自动实战

很多团队已经把 MySQL、Prometheus、Loki 和 Grafana 装起来了,但线上报警之后,值班人员仍然要在四个窗口之间来回切换:先看仪表盘,再写 PromQL,然后去日志里搜索 trace_id,最后登录数据库核对业务记录。
这就像医院明明有体温计、病历、化验单和监护大屏,医生却仍要自己跑四个房间抄数据。AI Agent 真正有价值的地方,不是替医生“猜病”,而是拿着受限制的工具,自动把四处证据取回来,再把“现象、证据、根因和建议”分开说明。
本文不是概念拼贴。我实际启动了一套隔离环境,使用 MySQL 8.4、Prometheus 3.13、mysqld_exporter 0.19、Loki 3.7 和 Grafana 13.1,注入了一次带统一 trace_id 的慢查询故障,然后通过自建只读 MCP Bridge 完成协议初始化、工具发现、PromQL 查询、LogQL 查询、MySQL 只读查询和 Grafana 数据源审计。
先说结论:四件套接入 Agent,不等于把四套管理员密码交给 AI
正确的架构应该满足下面几条:
- MySQL 仍然保存业务事实,Agent 只能使用专门的只读账号;
- Prometheus 负责保存数字随时间的变化,例如连接数、QPS 和缓存命中率;
- Loki 保存“发生了什么”的日志,并通过标签、时间和
trace_id关联事件; - Grafana 继续承担人工观察、仪表盘、数据源管理和结果复核;
- MCP Bridge 把查询包装成边界明确的工具,而不是开放任意 Shell;
- Agent 先调用工具取证,再总结答案,不能把语言模型的推测冒充事实。
换句话说,Agent 拿到的应该是一串“只能打开指定抽屉的钥匙”,而不是整栋楼的万能钥匙。

四件套分别是什么?用小学生也能懂的方式解释
MySQL:学校老师手里的成绩册
MySQL 保存订单、用户、库存、付款状态等业务事实。你问“这个订单到底有没有支付”,最终应该以数据库记录为准。
它像成绩册:里面写着谁参加了考试、得了多少分。成绩册擅长回答具体事实,却不适合每隔五秒画一次“全校平均分变化曲线”。
Prometheus:每隔几秒自动测一次体温
Prometheus 会定时抓取指标,并保存时间序列。借助 mysqld_exporter,MySQL 的连接数、查询数、线程状态等数据会被翻译成 Prometheus 能理解的格式。
它像自动体温计:一次读数只能告诉你现在是 38℃,连续读数才能告诉你温度是突然升高、持续升高,还是已经恢复。
下面是真实实验中的 Prometheus Targets 页面。mysql 抓取目标显示为 UP,说明 exporter 与 Prometheus 的链路已经打通。

Loki:值班室的事件记录本
Loki 保存日志,并使用 LogQL 查询。日志会告诉你“谁在什么时间做了什么、发生了什么错误、对应哪个 trace_id”。
它像值班记录:体温计告诉你病人发烧了,值班记录则可能写着“吃药十分钟后开始过敏”。两者合起来,才更接近真相。
Loki 与 Elasticsearch 的设计思路不同。Loki 通常不会给每一段日志正文建立重型全文索引,而是重点索引标签,再对选中的日志流做过滤。因此标签不能无限膨胀,user_id、订单号这类高基数字段通常更适合留在日志正文或结构化元数据中。
Grafana:把各种仪表放在一起的驾驶舱
Grafana 可以同时连接 Prometheus、Loki 和 MySQL。人类可以在一个界面里查看曲线、日志、表格和告警,也可以检查 Agent 给出的结论是否真的有数据支撑。
它像汽车驾驶舱:发动机、油箱和轮胎并没有被驾驶舱取代,驾驶舱只是把关键状态放在一个容易观察的位置。
为什么还需要 MCP Bridge?
大语言模型本身不能可靠地“看到”你的实时数据库和监控数据。即使模型知道 PromQL 语法,也不知道你此刻的 mysql_up 是 1 还是 0。
MCP 可以理解成酒店前台:客人不能随便冲进仓库,但可以向前台提出标准请求,例如“查询过去 30 分钟的错误日志”。前台检查权限、时间范围和参数后,再把结果返回。
本次实验中的 Bridge 暴露了四个工具:
mysql_readonly_query:只允许SELECT、SHOW和EXPLAIN,最多返回 100 行;prometheus_query:执行一次即时 PromQL 查询;loki_query:在受限时间窗口内执行 LogQL;grafana_datasources:读取 Grafana 数据源列表,用于审计 Agent 实际连接了什么。
下面是真实 MCP 会话截图。服务端完成初始化后,客户端发现四个工具,并实际查询到 mysql_up=1 和数据库事故记录。

实际故障场景:结账接口为什么变慢?
我向 Loki 写入了两条结构化日志:一条记录慢查询,另一条记录上游请求超时。两条日志使用同一个脱敏演示 trace_id。
慢查询日志包含这些字段:
{
"event": "slow_query",
"trace_id": "demo-trace-7f3a",
"duration_ms": 842,
"sql_shape": "SELECT COUNT(*) FROM orders WHERE customer_email LIKE ?"
}
注意我只记录了 SQL 形状,没有记录真实邮箱、参数和完整 SQL。这是生产日志非常重要的脱敏习惯。
下面是 Loki 查询接口返回的真实结果。它找到了 checkout-api 的 slow_query 事件以及对应的 trace。

Agent 的合理调查顺序不是“先写一篇答案”,而是:
- 查询 Prometheus,确认 MySQL 与 exporter 是否存活;
- 查询 Loki,找到错误时间、慢查询形状和 trace_id;
- 使用只读 MySQL 工具查询事故记录或相关业务状态;
- 检查 Grafana 数据源,确认查询目标没有接错环境;
- 最后才输出结论,并明确区分已经证实与仍需验证的部分。

本次实验最终得到的结论是:数据库存活,指标抓取正常;应用日志显示订单搜索耗时 842ms,随后请求超时;MySQL 事故记录指出演示查询使用了无法有效利用普通索引的前置通配符过滤。合理修复方向是调整查询方式、建立与查询条件匹配的索引或使用专门的搜索方案,而不是盲目重启 MySQL。
一键部署:Windows 11、Ubuntu 26.04、macOS 26
完整实验包已经放在本文配套下载目录中:
实验包会自动完成:生成随机密码、启动 MySQL、exporter、Prometheus、Loki、Grafana 和 Agent Bridge、注入演示故障日志,并生成 agent-mcp.json。
Windows 11
解压后,以 PowerShell 执行:
Set-ExecutionPolicy -Scope Process Bypass
.\install-windows-11.ps1
如果机器没有 Docker Desktop,脚本会通过 winget 安装并等待服务启动。
Ubuntu 26.04
chmod +x install-ubuntu-26.04.sh
./install-ubuntu-26.04.sh
如果没有 Docker,脚本会使用系统软件源安装 docker.io 和 Compose 插件。普通用户没有 Docker Socket 权限时,脚本会自动改用 sudo docker 启动实验。
macOS 26
chmod +x install-macos-26.sh
./install-macos-26.sh
脚本优先使用现有 Docker。如果本机没有 Docker 但已经安装 Homebrew,会安装 Docker Desktop 并等待它就绪。
启动完成后,本机浏览器可访问:
Grafana: http://localhost:13000
Prometheus: http://localhost:19090
所有端口只绑定到 127.0.0.1,不会默认暴露到局域网。停止实验使用:
docker compose down
连演示数据一起删除:
docker compose down -v
人工配置 Agent 的方法
安装脚本会在实验目录生成 agent-mcp.json,内容类似:
{
"mcpServers": {
"observability-lab": {
"command": "docker",
"args": [
"compose", "-f", "/your/lab/docker-compose.yml",
"run", "--rm", "-T", "agent-bridge"
]
}
}
}
把 observability-lab 这一段合并到你所使用的 Agent 客户端 MCP 配置中,然后重启客户端。不同客户端的配置文件位置不同,不要盲目覆盖整个配置文件。
连接后可以先让 Agent 执行低风险自检:
请列出 observability-lab 的可用工具。
调用 prometheus_query 查询 mysql_up。
调用 loki_query 查询最近 30 分钟 checkout-api 的 slow_query。
不得执行写入操作,不得修改任何配置。
让 Agent 自动配置的方法
如果你的 Agent 能读写本机配置,可以把下面这段要求交给它:
请在不覆盖现有 MCP 配置的前提下,读取当前目录的 agent-mcp.json,
把 observability-lab 合并到你的 MCP Server 配置。
修改前先创建带时间戳的备份;修改后重新读取配置并列出差异。
随后仅执行 tools/list 与 mysql_up 查询验证,禁止执行 SQL 写入、Shell 修改或容器删除。
自动化的重点不是“让 Agent 随便改”,而是把允许修改的文件、备份要求、验证动作和禁止事项写清楚。
我实际遇到的两个坑
配置文件明明存在,三个容器却同时 Permission denied
第一次把实验包从 macOS 打包到 Linux 时,MySQL、Prometheus 和 Loki 都报告无法读取挂载文件。根因不是镜像,也不是 YAML,而是归档后的权限变成仅属主可读,容器内的非 root 用户没有权限。
修复方法是让配置文件至少可读、目录可进入,初始化脚本可执行:
find . -type d -exec chmod 755 {} +
find . -type f -exec chmod 644 {} +
chmod 755 init.sh install-*.sh
Grafana 读取了 ._dashboards.yml 并因控制字符退出
第二个问题更隐蔽。macOS 归档产生的 AppleDouble ._* 元数据文件也被带到 Linux,Grafana 把 ._dashboards.yml 当成正式配置解析,最终报出“control characters are not allowed”。
根因是跨平台打包元数据污染,而不是 Grafana Dashboard JSON 错误。临时清理可以使用:
find . -name '._*' -delete
重新打包时应禁用 AppleDouble,或使用不会携带这些扩展元数据的发布流程。这个案例也说明:多个组件同时失败时,先找共同边界,例如文件权限、挂载、网络或环境变量,通常比逐个重装更快。
生产环境必须加上的安全边界

演示环境能运行,不代表可以直接照搬到生产。至少应增加这些限制:
- MySQL 单独创建只读用户,只授权指定库和视图;
- 不允许 Agent 接触 root、DDL、DML 和任意存储过程执行权限;
- SQL 解析器限制语句类型、返回行数、执行时间和并发;
- PromQL 与 LogQL 限制查询时间范围、返回条数和最大数据量;
- 对敏感日志字段做采集前脱敏,而不是查询后才遮盖;
- MCP 工具调用记录操作者、参数摘要、时间、结果大小和错误;
- Agent 的“建议”与实际变更分离,生产写操作必须人工审批;
- Grafana API Token 使用最小角色,并定期轮换;
- 不把数据库结果、日志全集和凭据复制到不受控的外部模型服务。
Q&A
已经有 Grafana,为什么 Agent 不直接读取 Grafana 页面?
网页是给人看的,DOM 会变化,截图也容易遗漏原始数值。Agent 更适合通过稳定 API 或 MCP 工具查询;Grafana 页面用于人工复核与可视化。
Agent 能不能直接自动修复?
技术上可以,生产上不建议一开始就做。先做到只读取证、生成建议和验证清单。等审计、回滚、权限和审批成熟后,再把少量低风险动作做成需要确认的工具。
MySQL、Prometheus、Loki 数据怎么关联?
最常用的纽带是时间、服务名、环境名和 trace_id。指标告诉你“什么时候开始异常”,日志告诉你“哪个请求出错”,数据库告诉你“业务事实是什么”。不要把订单号等高基数字段直接做成 Prometheus Label 或 Loki Label。
是否必须使用本文的自建 Bridge?
不必须。Grafana 官方已经提供 MCP Server,可以按实际权限和工具需求采用。本文自建 Bridge 的目的,是把只读 SQL、PromQL、LogQL 和 Grafana 审计放进一个容易看懂、可以完整离线检查的教学样例中。
这套环境是否依赖第三方 SaaS?
不依赖。数据留在本机 Docker 网络和本地卷中。下载安装镜像需要互联网,但运行、查询和 Agent 工具调用不依赖外部可观测性平台。
最后总结
MySQL、Prometheus、Loki 和 Grafana 不是四套互相竞争的软件:MySQL 保存业务事实,Prometheus 保存数字趋势,Loki 保存事件经过,Grafana负责统一观察。AI Agent 则像一名会使用这些工具的助手。
真正决定成败的不是模型有多聪明,而是工具是否只读、数据是否可关联、查询是否受限、结论是否引用证据、变更是否需要审批。
如果 Agent 只能聊天,它遇到故障时只能猜;如果 Agent 拿到了边界清楚的观测工具,它才有机会成为可靠的值班助手。
官方参考资料
- Prometheus HTTP API:https://prometheus.io/docs/prometheus/latest/querying/api/
- Prometheus mysqld_exporter:https://github.com/prometheus/mysqld_exporter
- Loki HTTP API:https://grafana.com/docs/loki/latest/reference/loki-http-api/
- Grafana 数据源自动配置:https://grafana.com/docs/grafana/latest/administration/provisioning/
- Grafana MCP Server:https://github.com/grafana/mcp-grafana
- MySQL 官方文档:https://dev.mysql.com/doc/