news 2026/9/8 21:12:32

运维Agent如何从“会回答”到“能处理”?以MySQL数据库故障为例

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
运维Agent如何从“会回答”到“能处理”?以MySQL数据库故障为例

晚上十一点半,运维群里的告警信息像开了闸一样涌出来:“MySQL 连接数超过阈值(当前 852/500)”“主从同步延迟 30 秒且在持续攀升”“CPU 使用率 98%”。你赶紧打开企业自己的智能运维 Agent 对话框,输入“数据库现在什么情况,怎么处理?”几秒钟后,Agent 回复了一大段标准答案:从排查连接数到检查慢查询,再到必要时切换主库。文字很流畅,结论也“正确”,但问题解决了吗?没有。因为没有人告诉它当前主库上还有两个长事务没有提交,没有人让它去核对连接到底来自哪个应用,它甚至连这台数据库的实例名都没查。

这就是我想聊的问题:企业运维 Agent 不能只会“回答”。它需要能看懂现场、判断根因、执行动作,甚至把一次故障的处理过程沉淀成下一次可复用的经验。这篇博文以一次完整的数据库故障处理过程为线索,拆解一个能干活、敢干活、不掉链子的运维 Agent 应该具备的能力,同时也把我踩过的坑和调整思路一并写出来。内容更适合正在做运维平台、AI Agent 开发、数据库管理的人参考,也适合已经厌倦了“只会查文档”的聊天机器人的运维同学。

1. 故障现场:一条告警背后的真实混乱

1.1 故障回顾:从告警到响应的最初 15 分钟

先交代一下背景。那套系统是一个典型的电商订单库,MySQL 8.0 三节点 MGR 集群,业务侧读多写少,平时连接数稳定在 200 到 300 左右。某天晚高峰刚过,告警平台在 23 点 30 分开始连续上报,监控截图上的数据大致是这样的:

监控项正常值故障值
活跃连接数200 ~ 300852,持续上涨
CPU 使用率20% ~ 40%98%
活跃事务数0 ~ 530+
锁等待次数0每秒 40+
主从同步延迟0 ~ 1s30s 且持续攀升
磁盘 IO 等待5ms120ms

第一轮告警出现时,大家最先想到的是“是不是又有开发同事跑了一把大查询”。但打开慢查询日志,里面并没有特别离谱的十几秒 SQL,反而是大量执行时间在 100ms 到 300ms 的中低频 SQL 堆积。这时候 Agent 如果只会“回答”,它可能会直接给出“请开启慢日志分析”或者“建议添加索引”,但现场的核心矛盾已经不在单条 SQL 性能上了,而是连接数被打满,新请求全部排队。

前 15 分钟我们其实做了一系列手工操作:先确认 MGR 三个节点状态,再看主库和从库的复制通道,然后用SHOW ENGINE INNODB STATUS抓取事务和锁信息。当看到一段明显的“线程 9909 正在等待一张订单明细表的行级锁,而持有锁的事务已经空闲了 60 秒”时,问题才逐渐清晰起来。也就是说,真正的问题不是数据库突然变慢,而是有个应用连接拿住事务不提交,把一批后续写操作全部堵住了。

这类问题在互联网公司很常见,但“常见”不等于“好处理”。尤其当 Agent 只针对告警标题做知识匹配时,它容易把“连接数高”这个结果当成根因,然后给出一堆无关建议。真正的诊断需要结合连接来源、事务状态、锁等待链、复制延迟等多个维度。

1.2 为什么“会回答”不等于“会运维”

早些时候,我们团队内部做过一次对比测试:把同一份故障描述发给三套不同的“运维大模型助手”,结果它们几乎都给出了结构很完整、措辞很专业的排查手册。有的建议查慢日志,有的建议 kill 掉空闲事务,有的建议直接切换主库。问题在于,没有一套方案结合实际监控指标做推理,也没有一个助手告诉我“需要先拿到 processlist 才能判断”。换句话说,它们是在“回答问题”,不是在“处理故障”。

“会回答”的本质,是从知识库里检索出与当前问题文本最相似的历史文档。这种方式对标准化故障有一定帮助,比如“磁盘空间满怎么处理”“主从延迟一般原因有哪些”,因为这类问题通常有明确的操作手册。但数据库故障更像一个非线性的系统问题:连接数打满可能是慢查询导致,也可能是连接池泄漏导致,也可能是锁等待导致,甚至可能是磁盘故障导致。文本相似度无法区分这些场景。

真正的运维 Agent 应该像一个一线工程师,先看现场再下结论。它至少要能做以下几件事:

  • 自动采集当前实例的会话、状态变量、锁等待、复制延迟等核心指标;
  • 根据指标变化给出候选根因,而不是只根据问题文本来匹配;
  • 对自己给出的每条结论提供数据证据,比如“哪个会话、哪条 SQL、等待了多久”;
  • 在人工审批允许的前提下,直接执行安全动作,而不是只丢给用户一段命令让用户自己复制。

这四件事,有任意一件缺失,Agent 就只是一个“高级版搜索框”。我把这种从“感知到执行再到反馈”的链路称为故障处理闭环,下面要讲的完整案例,就是围绕这个闭环展开的。

2. Agent 的角色边界:从“问答机器人”到“故障处理执行者”

2.1 我理想中的运维 Agent 能力分层

在落地之前,我们先把 Agent 的能力拆成了四层。这个分层不是理论推演,而是为了在实际开发中明确边界:不能让一套模型把所有事情都干了。

能力层核心职责典型动作失败后果
感知层获取数据库与系统的实时状态拉取监控、执行只读 SQL、读取日志拿不到数据,后面全是瞎猜
判断层对现象做根因分析与假设排序对比指标、识别锁等待链、分析慢查询判断错方向,处理动作全错
执行层在审批和安全边界内执行动作回收连接、杀掉会话、触发工单、切换只读权限过大可能造成二次故障
复盘层沉淀本次故障的经验与数据输出报告、更新知识库、标记预案知识不沉淀,下次还得踩坑

感知层是根基。很多 Agent 项目一上来就做大模型、做知识库,却忽略了“连数据库操作权限都没有”。没有感知层,Agent 就只是一个记忆库,它不知道当前实例是主还是从,不知道连接数是多少,不知道这条 SQL 写到哪张表。判断层则负责把感知层的数据转化为候选根因,通常也是大模型加上规则脚本混编的部分。执行层强调安全和可靠,在数据库故障场景里尤其要谨慎。复盘层则决定了这个 Agent 是不是越用越聪明。

四层之间并不是严格的串行链路,而是可以带反馈的环:执行完一个动作后,感知层要重新采集指标,判断层要确认“执行前假设是否成立”。比如 Agent 判断是“空闲事务阻塞”,执行了 kill 后,应该立刻再查锁等待是否消失,而不是直接宣布故障恢复。

2.2 数据库故障场景下 Agent 必须拿下的关键技术点

既然要处理数据库故障,Agent 不能只懂通用“数据库增删改查”。它至少要对下面这些场景形成条件反射,而且每个场景都要知道对应的采集命令和判断逻辑。

连接管理。连接数被打满是最常见的故障入口。Agent 需要能查information_schema.processlist,并按照user,host,db,command,state字段做聚合,找出连接来源是哪个应用实例,哪些连接处于Sleep状态但没有释放,哪些连接在Query状态下卡了很久。判断是否是连接池泄漏时,需要对比同一来源 IP 在不同时刻的连接数变化。

锁等待与死锁。传统优化偏重索引和慢查询,但实际生产里的锁问题比想象中多。Agent 需要会看sys.innodb_lock_waitsperformance_schema.data_lock_waits,把阻塞链路中的“谁等谁”梳理出来,并关联到具体事务的起始时间和持有的行锁数量。出现“数据库死锁”告警时,还要能分析SHOW ENGINE INNODB STATUS里 LATEST DETECTED DEADLOCK 段,定位是哪两条 SQL 在交叉加锁。

慢查询定位。慢查询不能只看执行时间,还要看 SQL 的扫描行数和返回行数。Agent 需要能读取 MySQL 慢日志或性能库中的统计信息,识别出“低频但每次执行代价很高”和“高频但单次不慢”两类问题。前者通常是缺少索引,后者通常是连接风暴或锁等待叠加。

主从复制与数据一致性。对集群数据库来说,主从延迟是另一个高频问题。Agent 不仅要会看SHOW REPLICA STATUS里的延迟字段,还要对 MGR 等架构有自己的判断逻辑,比如从库回放线程是否卡在临时表、大事务是否拖慢提交、网络带宽是否打满。处理延迟时不能盲目切换主库,必须先确认从库是否追平了 binlog。

备份与恢复认知。故障处理里最容易慌的就是“要不要回滚数据”。Agent 必须知道当前集群是否有最近的全备和 binlog,知道备份文件存放在哪个区域,知道恢复一个表需要大概多长时间。这些问题如果回答不了,它在紧急情况下就只是个“会说话的告警提示器”。

我把这类能力称为“数据库故障处理基础套餐”。如果一个 Agent 连这些都不知道,它不可能承担真正的应急操作,只能做一些文档问答。

3. 一次完整的数据库故障处理:Agent 应该怎么做

3.1 步骤一:故障采集与现象收敛

回到那次故障。在确定了“连接数持续上涨,锁等待增多”后,我们希望 Agent 能自动执行一套采集动作,而不是等工程师去手工敲命令。设计上,Agent 收到告警后,会并行启动几个只读巡检任务,全部基于一次快照采集:

采集项对应命令/信息来源解决什么问题
活跃会话和来源information_schema.processlist聚合查询连接打满还是会话堆积
锁等待关系sys.innodb_lock_waits谁在等谁,阻塞源头在哪
当前事务详情performance_schema.data_locks识别长事务和未提交事务
InnoDB 引擎状态SHOW ENGINE INNODB STATUS死锁、信号量、恢复状态
复制延迟MGR 视图 /SHOW REPLICA STATUS集群是否健康
慢 SQL 统计performance_schema.events_statements_summary_by_digest哪些 SQL 消耗高

这里有一个很容易忽略的细节:采集一定要“一次性快照”而不是“逐条命令慢慢查”。如果 Agent 先查 processlist,再查锁等待,中间隔了好几秒,连接情况可能已经变了,前后的数据没法对齐。我们最后用 Python 脚本在同一个事务里对这些系统表做多表关联查询,这样能拿到一个相对一致的现场。

采集完成后,Agent 的“感知层”会输出一份结构化现象描述。当时的关键输出是:

  • 活跃连接中,来自应用 “order-api-v3” 的连接占 402 个,其中Sleep状态超过 60 秒的有 233 个;
  • 出现锁等待的 SQL 集中在一张订单明细表上,被阻塞会话数为 86;
  • 持有锁的事务来自 IP 10.20.31.18,事务启动时间为 23:19:40,至今未提交;
  • MGR 状态正常,但从节点由于回放积压导致查询延迟。

有了这份“现象收敛结果”,Agent 才真正从“它知道有问题”进入到“它知道哪里有问题”。

3.2 步骤二:根因分析与假设排序

拿到现象后,Agent 不能直接跳到结论。我们给它的判断层设计了一套“假设-验证”循环,先枚举最可能的根因,再逐条验证:

  1. 连接池泄漏:表现为连接数持续上涨、但活跃查询不多、Sleep 连接占大多数;
  2. 长事务未提交引发行锁堆积:表现为大量写操作阻塞、锁等待次数升高、活跃事务数增加;
  3. 慢查询拖垮 CPU:表现为单条 SQL 执行时间很长、扫描行数巨大、CPU 和 IO 同时高;
  4. 硬件或存储故障:表现为 IO 延迟很高、磁盘繁忙、日志报错。

Agent 按照“影响面优先”的顺序做排序。虽然当时 CPU 使用率 98% 最刺眼,但它应该先回答“CPU 是被 SQL 打高,还是被锁等待堆积的副作用打高”。判断方法很简单:看processlist里处于Query的会话多不多,如果大量会话都在StatisticsWaiting for lock状态,说明 CPU 可能是在空转,真正的问题是锁。

实际诊断 SQL 类似这样:

SELECT id, user, host, db, command, time, state, LEFT(info, 120) AS current_sql FROM information_schema.processlist WHERE command <> 'Sleep' ORDER BY time DESC LIMIT 20;

这个查询会把当前非 Sleep 的最长会话捞出来。当时的输出里,排在第一位的是SELECT ... FROM order_detail WHERE order_id = ? FOR UPDATE,state 是Waiting for lock,已经等待了 79 秒。紧随其后的是一堆INSERT语句,全部卡在行锁等待上。这就基本确认了“锁等待”是主矛盾,而锁的源头是那个 23:19 开始、至今未提交的事务。

Agent 想要进一步确认,可以查sys.innodb_lock_waits

SELECT r.trx_id AS waiting_trx_id, r.trx_mysql_thread_id AS waiting_thread, TIMESTAMPDIFF(SECOND, r.trx_started, NOW()) AS waiting_age, b.trx_id AS blocking_trx_id, b.trx_mysql_thread_id AS blocking_thread, b.trx_started FROM sys.innodb_lock_waits w JOIN information_schema.innodb_trx r ON w.waiting_trx_id = r.trx_id JOIN information_schema.innodb_trx b ON w.blocking_trx_id = b.trx_id;

查询结果非常清楚:阻塞者线程是 9909,事务从 23:19:40 开始,持续了 10 分钟以上;等待者是一大批来自订单写服务的连接。根因假设“长事务未提交导致行锁堆积”得到确认,Agent 也同时收集到了执行动作所需的全部上下文。

3.3 步骤三:执行动作与人工审批

根因确认后,Agent 能给出的处理手段不止一种。我们先说最安全的动作,再说需要更强权限的动作。

最安全的是“回收空闲连接”。对应命令是:

-- 找出空闲超过 60 秒的连接,生成 kill 语句 SELECT CONCAT('KILL ', id, ';') AS kill_statement, user, host, db, time, state FROM information_schema.processlist WHERE command = 'Sleep' AND time > 60 LIMIT 200;

但这里必须谨慎:不能把所有 Sleep 连接都杀掉,因为有些连接是连接池里的保活连接,被杀后虽然应用会自动重连,但短时间内会引发连接风暴。更安全的做法是先按来源 IP 和用户维度做统计,确认哪些 IP 下的连接数异常,再针对这些连接执行清理。

针对阻塞源头,最终要处理的是线程 9909 所在的未提交事务。Agent 不能直接执行KILL 9909,因为如果这个事务里还有未提交的业务逻辑,强杀可能会导致部分数据回滚,业务侧可能需要感知。所以我们的流程是:Agent 生成操作建议,先发到审批单上,由当班 DBA 确认,同时 Agent 通过运维平台给业务负责人发通知。

最终审批通过后,执行了:

-- 终止阻塞会话 KILL 9909;

执行完成后,Agent 自动进入“验证阶段”:再次查询sys.innodb_lock_waits,确认锁等待记录已经清空;然后观察活跃连接数是否在回落。我这里拿到的结果:执行 kill 后 30 秒,锁等待次数从每秒 40+ 降到了 0,活跃连接数从 852 降到 560,业务连接池开始自动回收释放连接,大约 7 分钟后系统恢复正常。

这里想强调一个原则:Agent 可以提方案、生成命令、调用系统 API,但最终执行前必须有人工授权。即便要追求全自动,也应该先在一个受限环境里跑足够长的时间,而且每一次执行动作都要有回滚方案。数据库不是普通的 IT 资源,一旦误操作,恢复成本很高。

3.4 步骤四:故障复盘与知识沉淀

故障恢复不等于处理结束。后面更重要的一件事是,把这次故障变成 Agent 下一次遇到类似问题的“反射”。

复盘中我们梳理了三个导致故障的深层原因:

  1. 业务应用 order-api-v3 使用了旧版数据库连接池,未设置maxLifetime和空闲超时释放,导致大量空闲连接长期占用;
  2. 订单详情查询语句在事务内先SELECT ... FOR UPDATE锁行了记录,又执行了远程接口调用,使得事务时间被拉长到一个不合理范围;
  3. 数据库侧的锁等待监控没有配置对应告警,直到连接数打满才触发,错过了最早的干预窗口。

Agent 在复盘层的输出不是一篇给领导看的 Word 文档,而是一个可以嵌入知识库的结构化记录,包括故障现象特征、根因假设、证据链、执行动作、恢复时间、后续改进项。我们的做法是把这些信息抽取成 JSON 字段,再写入向量数据库,同时挂到对应预案标签下。

举个例子。如果后续某天又出现“连接数上涨 + 锁等待 + 活跃事务多”的组合,Agent 在做假设排序时,会把“长事务未提交”的概率提到很高的位置,并第一时间去检查innodb_trx表和锁等待关联,而不是先反复分析慢日志。这就是知识沉淀带来的直接价值。运维 Agent 的价值,不是体现在它背下来多少文档,而是体现在它在故障发生时能更快、更准确地找到证据和做出行动。

4. 搭建 Agent 处理数据库故障时,需要避开的坑

4.1 坑一:把向量数据库检索当成故障诊断的全部

现在很多 Agent 项目都会接向量数据库,把操作手册、历史工单、故障报告切片后塞进去。这个思路本身没有问题,问题在于把向量检索当成唯一能力。我调研过一些团队做的运维 Agent,它们本质上就是“查询增强生成”的套壳:你问“数据库死锁怎么处理”,它把文档里的“死锁产生的原因”背出来,但如果当前库里已经真的发生了死锁,它并不知道。

原因很简单:向量数据库存的是“语义碎片”,不是“实时状态”。当你问“现在这台数据库死锁怎么处理”,Agent 需要先查询当前的死锁记录、等待关系、事务状态,也就是用 SQL 去查系统表,再用检索到的文档辅助判断。正确做法是让结构化查询和语义检索各司其职:监控数据、系统状态、锁关系通通走 SQL;历史案例、操作规范、踩坑经验走向量数据库。两个结果合并后,再交给大模型做推理。

我们在设计时做了一个很关键的小改动:如果 Agent 的答案没有引用任何“实时采集指标”,系统会直接标记为“未验证建议”,不能自动执行。这个机制能挡住很多看似正确但实际没有任何用处的回答。

4.2 坑二:权限边界没设计好

让 Agent 去执行数据库命令,权限给多大是个棘手问题。给大了,一个误判就可能把整个集群搞挂;给小了,Agent 什么也干不了,又回到“只会回答”的状态。

我建议按下面这个矩阵拆权限:

操作类型示例权限要求
只读巡检查询 processlist、查看锁等待、读监控Agent 可直接执行,无需人工审批
轻量变更kill 空闲超过阈值的连接,清理临时会话Agent 可发起,需当班 DBA 一键审批
重型变更kill 持有长事务的会话、重启实例、切换主库必须双人审批,且 Agent 需提供证据链
破坏性变更drop 数据、truncate 表、格式化存储默认禁止,必须走完整变更流程

还有一个容易被忽略的细节:Agent 申请执行高危命令时,不能只说一句“我要执行 KILL”。它需要把“杀哪个连接、这个连接在跑什么事务、影响哪些业务、回滚方案是什么”全部列出来。这个要求不是刁难,而是迫使 Agent 在执行前真正理解自己要做的事。我们第一次踩坑时,就是因为 Agent 直接给了一个KILL 9909的结论,但说不清楚这个连接到底在做什么,后来改成模板化审批单才解决。

4.3 坑三:缺少“回答必须可验证”的机制

Agent 给出的结论一定要能验证。我见过不少团队在评估 Agent 效果时,只看“回答是否专业”“步骤是否齐全”,却忽略了一个核心问题:这些回答放到真实故障现场,有没有用?

我们内部把验证机制分成三层:

第一层是证据完整性:每条根因判断都要附上对应的数据证据。说“连接池泄漏”,必须给出同一来源 IP 的连接数变化曲线;说“锁等待严重”,必须给出sys.innodb_lock_waits的查询结果。

第二层是操作可回滚性:Agent 每次执行动作前,要生成一个“执行前状态快照”和“回滚脚本”。执行完后再对比快照,判断动作是否真的起了作用。

第三层是复盘一致性:故障结束后,Agent 自己要对整个处理过程打分,看预判的根因和最终根因是否一致。如果 Agent 一开始判断错了,系统会把错误链路记录下来,作为后续模型训练和规则修正的样本。

有了这三层,“Agent 不会乱说话”就不是靠提示词约束,而是靠流程约束。很多 AI 项目的失败,不是模型能力不够,而是没有用工程手段把模型限制在“可验证”的边界里。

5. 这类 Agent 到底要学哪些东西:给运维和开发同学的能力清单

5.1 数据库基本功:建议同时掌握传统关系库和国产库

想做出能真正处理数据库故障的 Agent,开发者和运维同学首先要过数据库基本功这一关。我的建议是,不要只盯着 MySQL 一门课死磕,最好按照“一套传统关系库 + 一套国产库”的组合来学。现在企业里 Oracle、MySQL 还有大量存量,达梦、Doris 这类国产或大数据分析型数据库也越来越多。Agent 能连的库种类越多,适用面越广。

学习路径可以从“安装-增删改查-事务-锁-集群-备份恢复”这样走:

  • 先手动安装一遍 MySQL 和达梦数据库,搞懂客户端连接、用户权限、配置文件里的关键参数;
  • 再练习数据库增删改查,重点理解事务隔离级别和锁机制;
  • 然后用SHOW ENGINE INNODB STATUS和系统视图模拟锁等待、死锁;
  • 最后搭一套主从或集群环境,练习切换、延迟排查、备份恢复。

这个过程听着像数据库课程设计,但非常值得。因为你只有亲手踩过锁等待的坑,写 Agent 的规则时才知道data_lock_waits里每一列代表什么;只有亲自把备份恢复到另一个实例,才知道 Agent 报出的恢复时间大概有多大的误差。

5.2 给 Agent 增加“操作技能”:从生成 SQL 到执行动作

在这个项目里,我们并没有用一个特别复杂的 Agent 框架,而是先把“单步能力”做扎实。核心思路是让 Agent 可以连接数据库执行只读诊断,并把结果交给上层做判断。一个简单的例子是用 Python 连接 MySQL,拉取当前 processlist 信息:

import pymysql import json def collect_processlist(host, user, password, port=3306): conn = pymysql.connect( host=host, user=user, password=password, port=port, connect_timeout=5 ) with conn.cursor() as cur: cur.execute(""" SELECT id, user, host, db, command, time, state, LEFT(info, 200) AS sql_text FROM information_schema.processlist WHERE command <> 'Sleep' ORDER BY time DESC LIMIT 50 """) rows = cur.fetchall() cols = [desc[0] for desc in cur.description] conn.close() return [dict(zip(cols, row)) for row in rows] if __name__ == "__main__": result = collect_processlist( "127.0.0.1", "monitor", "your_password" ) print(json.dumps(result, ensure_ascii=False, indent=2))

这段代码是 Agent 的“感知层”入口。拿到返回结果后,再交给判断层或大模型做结构化总结。如果要让 Agent 执行KILL,我们不会让它直接用这个账号去操作,而是通过运维平台的 API 提交一个工单,带上目标线程 ID 和执行理由。这样既能执行动作,又能留痕和审批。

至于 Agent 的编排框架,用简单的if-else或者像 LangGraph 这类带状态流转的工具都可以。重点是准备好这些可以被调用的原子动作,例如collect_processlist,check_lock_wait,get_replication_status,kill_session_with_approval。没有这些原子动作,Agent 就只能“说”,不能“做”。

5.3 一个最小可用的故障处理 Agent 实现思路

考虑到很多人想快速跑通一个 Demo,我分享一下我们的最小实现思路。它不需要复杂的模型训练,核心逻辑非常简单:

def handle_database_fault(alert): if alert.metric != "connection_usage": return "暂不支持的告警类型" # 1. 感知:拉取现场数据 snapshot = collect_snapshot(alert.instance_id) # 2. 判断:根据规则做候选根因排序 hypotheses = rank_hypotheses(snapshot) # 3. 决策:如果规则置信度低,再调大模型辅助 if hypotheses[0].confidence < 0.7: hypotheses = llm_analyze(snapshot, hypotheses) # 4. 执行:先申请审批,审批通过后执行动作 action = generate_action(hypotheses[0], snapshot) approval = request_approval(action) if approval.passed: execute(action, snapshot) # 5. 复盘:执行后重新拉取现场数据,确认是否缓解 verify_and_report(action)

这段伪代码已经把前面说的“感知-判断-执行-复盘”闭环串起来了。实际生产环境里,rank_hypotheses可能是一组规则加统计模型,llm_analyze才会用到 Agent 的语言能力,request_approval对接审批系统,execute对接运维平台 API。整体上,你可以把它理解成一个“带大脑的自动化运维脚本”,大模型负责把规则覆盖不到的场景总结出来,但核心控制权仍然掌握在可控、可回滚的工程代码里。

6. 现场实录:从“答非所问”到“稳定处置”

6.1 第一次实践时的失败记录

这个系统不是一开始就跑得这么顺。最早我们做的 v1 版本,真的差点把生产环境搞出更大的事。

当时 Agent 接到一个和本次场景很像的告警,它给出的建议是“直接重启数据库实例”。理由是知识库里有这样一条历史工单:连接数打满、CPU 高,重启后恢复。它就这样原封不动地复述了出来。幸好当班 DBA 没有按下执行按钮,而是手工复查了一遍事务状态,发现这库上有两个已经运行了 20 多分钟的大事务,如果按 Agent 建议强制重启,数据库启动后会进入崩溃恢复流程,binlog 回放和 undo 清理会让恢复时间从预计的 5 分钟拉到 40 分钟以上,业务损失会更大。

复盘这次失败,问题不在于大模型不会推理,而在于我们没给它足够的“现场约束”。它没有在回答问题前先拉取innodb_trx,没有检查是否有大事务,也没有把“重启可能引发崩溃恢复”这一风险写进决策条件。这就像一个人没有任何乐器知识,只听别人说“弹钢琴时按白色按键就行”,然后就在演出前乱按一通。

从那以后,我们把“采集现状”作为所有建议的前置条件,并且加入了一条硬规则:没有拿到实时数据之前,Agent 禁止给出高风险的处置动作建议。这条规则虽然简单,但立刻让 Agent 的建议质量提高了一个档次。

6.2 调整后成功的操作复盘

到这次“长事务阻塞 + 连接数打满”的故障时,Agent 的表现已经比较接近我理想中的状态了。

故障开始后,Agent 自动执行了以下步骤:

  1. 收到“连接数持续上升”的告警,触发collect_snapshot采集脚本;
  2. 通过processlist聚合发现order-api-v3的连接数异常,且大量连接处于 Sleep;
  3. 通过sys.innodb_lock_waits找到阻塞源头是线程 9909,事务已运行 10 分 40 秒;
  4. 生成了两个处置建议:清理空闲连接、终止线程 9909;
  5. 将操作建议钉到审批流,附上了锁等待查询结果和影响分析;
  6. 经 DBA 审批通过后,执行KILL 9909,并自动重新采集锁等待数据;
  7. 确认锁等待清空、连接数回落,输出结构化故障报告并写入知识库。

整个过程从告警到最终恢复大约 24 分钟,其中人工审批等待占了一部分时间,真正执行和处理只用了不到 10 分钟。相比过去人工翻监控、写 SQL、等确认,效率提升非常明显。

我更看重的,是 Agent 在这件事里证明了它能提供“证据链”:它不是因为“猜”而做出决策,而是因为看到了锁等待关系、看到了未提交事务、看到了连接来源,才有信心提出处理方案。企业运维 Agent 的价值,恰恰就在这些看得见摸得着的细节里。

说回我自己,我现在做运维 Agent 时,总会提醒团队三句话:先采集再说话,所有动作都要有审批和回滚,没有可视化证据的回答不要自动执行。这三条看起来很朴素,但每一条都是用真实故障换来的。Agent 的前景不在“会聊天”,而在“能扛事”,能把一次数据库故障从头到尾扛下来,才算真正迈过了企业运维的第一道门槛。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 21:12:31

STM32+ENC28J60+uIP嵌入式Web服务器实战:从硬件到应用

简介&#xff1a;一份基于STM32ENC28J60UIP协议栈的嵌入式WEB服务器示例&#xff0c;适合物联网入门开发者与嵌入式学习者&#xff0c;解决在资源受限单片机上实现HTTP服务、远程时间查看与设备控制的需求。压缩包共252个文件&#xff0c;磁盘占用约56.68MB&#xff0c;工程包含…

作者头像 李华
网站建设 2026/9/8 21:12:11

OpenHands PTY沙盒:为AI Agent装上可执行命令的物理手脚

1. 为什么 Agent 需要一副“物理手脚”很多人把 Agent 的开发理解成“套一个 Prompt、接一个大模型 API、能对话就算完事”。但真正做过 Agent 项目的人应该都有同感&#xff1a;对话能力只是 Agent 的“大脑皮层”&#xff0c;真正让 Agent 从“聊天机器人”升级为“能办事的智…

作者头像 李华
网站建设 2026/9/8 21:11:47

Qt+ffmpeg+OpenGL播放器开发实战:从解码到渲染的完整实现

简介&#xff1a;这是一份基于Qt、FFmpeg与OpenGL实现的播放器完整源码工程&#xff0c;面向具备C/Qt基础、希望深入理解视频解码与GPU渲染流程的开发者。工程采用VS与Qt联合编译&#xff0c;内置FFmpeg的64位库文件&#xff0c;无需额外安装依赖库即可直接构建运行&#xff0c…

作者头像 李华
网站建设 2026/9/8 21:11:43

Agent Zero 模型配置:最常见的 4 个卡点,逐个拆到跑通

Agent Zero 模型配置&#xff1a;最常见的 4 个卡点&#xff0c;逐个拆到跑通 【免费下载链接】agent-zero Agent Zero AI framework 项目地址: https://gitcode.com/GitHub_Trending/ag/agent-zero 装好 Agent Zero 之后&#xff0c;最容易卡住的一般就是模型配置&…

作者头像 李华
网站建设 2026/9/8 21:11:14

Agent Zero 完全上手指南:三步跑起一台带真 Linux 电脑的 Agent

Agent Zero 完全上手指南&#xff1a;三步跑起一台带真 Linux 电脑的 Agent 【免费下载链接】agent-zero Agent Zero AI framework 项目地址: https://gitcode.com/GitHub_Trending/ag/agent-zero Agent Zero 是一个开源智能体框架&#xff0c;把一整套 Linux 桌面装进 …

作者头像 李华