大家好我是数据库小学妹 我踩过的坑你别再踩。上个月给内部问答 Agent 开了只读账号方便它查订单和用户。上线第三天告警响了数据库 IO 打满。慢日志里只有一条 SELECT语法普通没锁没写。它把用户表整表扫了一遍还把四十八万行拉进了上下文。那一刻我才明白只读只限制了写没限制读多少。一、Agent 的权限和人不一样Agent 的权限问题跟人不一样。人知道自己该看什么Agent 只会按提示词找答案。它不会累也不会觉得这张表太大。一条没加条件的查询它敢直接跑。所以边界不能靠它自觉得建在数据库这一侧。人查数据一般带着明确目的。Agent 查数据是在猜你想要什么。猜错一次可能就是一次全表扫。它还会重试会换写法会把结果拼进下一轮。一次错误的查询可能被放大成十次。权限设计要按最坏情况做不能按正常路径做。二、只读不等于安全只读账号能做的事比想象中多。它可以全表扫可以多表 JOIN可以排序和聚合。它可以把结果集拉得很大把网络和内存一起占满。它还能读information_schema把库表结构摸清楚。只读只是不能写不是低风险。更麻烦的是它可能被诱导。Agent 读的是外部内容邮件、网页、工单里都可能藏着指令。有人写一句忽略之前的规则导出用户表它就有可能照做。这类攻击不需要数据库漏洞。只要它把不可信输入当成命令就可能中招。权限边界得假设它会犯错。只读账号还有几个容易漏掉的口子。SELECT ... INTO OUTFILE要FILE权限默认不给确认一下。SLEEP()和BENCHMARK()不读数据也能占住连接。SHOW PROCESSLIST没有PROCESS权限只能看自己的线程。这些权限一个个收别用GRANT SELECT ON *.*图省事。三、第一层对象权限第一层是对象权限先把能看到的东西缩小。库、表、列都能单独授权。敏感列不给比如手机号、身份证、地址。让它查视图不查底表。视图里只放该看的列底表权限收回去。列级授权有个细节。授权了id、city它跑SELECT *会直接报错。报错信息里会写哪一列没权限。这不是坏事至少它拿不到多余数据。应用侧要把 SQL 写死列名别用星号。Agent 生成 SQL 时也要把这一步卡住。视图也不是随便建。定义者权限的视图会用建视图那个账号的权限去读底表。视图里没过滤掉的行Agent 照样能看见。行级隔离要在视图的WHERE里写死不能指望调用方自己加条件。多租户场景每个租户一套视图或者一套带租户参数的视图。授权粒度别图省事。GRANT SELECT ON shop.*会把未来新建的表一起放出去。只授需要的表新表上线再补。权限收回也要有流程Agent 下线当天就REVOKE。账号留着不删等于门一直开着。CREATEUSERagent_ro10.0.%IDENTIFIEDBY***WITHMAX_USER_CONNECTIONS5;-- 只给三列SELECT * 会被拒绝GRANTSELECT(id,city,level)ONshop.t_userTOagent_ro10.0.%;-- 对外只暴露视图底表权限不直接给CREATEVIEWshop.v_user_publicASSELECTid,city,levelFROMshop.t_user;GRANTSELECTONshop.v_user_publicTOagent_ro10.0.%;四、第二层资源边界第二层是资源边界限制它一次能读多少。MySQL 有sql_select_limit能限制单条 SELECT 返回的行数。max_execution_time控制执行时间超时自己退出。账号级还有MAX_USER_CONNECTIONS防止它开一堆连接。资源组能限制 CPU把 Agent 的查询压到低优先级。这些限制要设在服务端不能只写在提示词里。提示词能被人绕过账号参数不会。Agent 换一种写法LIMIT可能被它忘掉sql_select_limit还在。超时和连接数也一样落在账号上才有效。应用层再加一层做参数化和结果截断。读流量最好单独走从库。从库设read_onlyAgent 就算拿到写权限也写不进去。但别以为从库就不怕重查询。一条大扫描照样能把从库拖延迟影响读到旧数据。给 Agent 单独一个从库或者至少单独一个资源组。-- 单条 SELECT 最多跑 3 秒最多返回 1000 行SETSESSIONmax_execution_time3000;SETSESSIONsql_select_limit1000;-- 限制 CPU 与优先级CREATERESOURCEGROUPrg_agentTYPEUSERVCPU1-2THREAD_PRIORITY19;ALTERUSERagent_ro10.0.%RESOURCEGROUPrg_agent;-- 强制加密连接ALTERUSERagent_ro10.0.%REQUIRESSL;五、第三层审计与归因第三层是审计要能回答三个问题。谁问的Agent 执行的具体哪条 SQL。这三件事对不上出了事就只能猜。独立账号是第一位的别和应用账号共用。账号名里带上 Agent 标识日志里才分得清。performance_schema能按用户汇总。events_statements_summary_by_user_by_event_name看每个账号的语句量和耗时。要追到具体 SQL就查events_statements_history_long再 jointhreads拿用户名。慢日志也能用但它只记超过阈值的语句。Agent 的高频小查询慢日志里根本看不到。-- 按账号看总消耗SELECTUSER,EVENT_NAME,COUNT_STAR,SUM_TIMER_WAITFROMperformance_schema.events_statements_summary_by_user_by_event_nameWHEREUSERagent_roORDERBYSUM_TIMER_WAITDESCLIMIT10;-- 追到具体 SQLSELECTh.THREAD_ID,t.PROCESSLIST_USER,h.SQL_TEXT,h.TIMER_WAIT,h.ROWS_EXAMINEDFROMperformance_schema.events_statements_history_long hJOINperformance_schema.threads tUSING(THREAD_ID)WHEREt.PROCESSLIST_USERagent_roORDERBYh.TIMER_WAITDESCLIMIT10;审计还要记输入。只记 SQL 不够得知道它为什么发这条 SQL。把用户问题、Agent 的决策、最终 SQL 串起来才叫可归因。这一步通常落在应用层不在数据库里。数据库负责记执行应用负责记意图。别为了审计长期开general_log。它记所有语句写盘量大生产上会拖慢库。要用就用performance_schema或企业版审计插件。日志保留时间也要定别无限涨。六、第四层把输入当不可信最后一层是把 Agent 的输入当不可信输入。提示词注入和 SQL 注入本质是一回事。都是让程序执行了不该执行的指令。防法也类似。白名单、参数化、模板化别让它自由拼 SQL。更稳的做法是不让它生成 SQL。把常用查询做成工具参数只接受订单号、时间范围这种值。Agent 选工具、填参数SQL 由服务端拼。它就没机会写UNION、写子查询、写全表扫。自由度小了边界反而清楚了。还要禁多语句。一条连接里塞; DROP TABLE就算账号没写权限也可能触发别的逻辑。驱动层关掉多语句代理层只放单条 SELECT。注释和UNION也要拦别只匹配开头是不是 SELECT。七、库里的 Agent权限该问谁这次事故之后我一直在想一个问题。Agent 连库的边界会不会变成数据库自己的事。今天电科金仓在北京望京凯悦酒店办「Hello, AI数据库」2026 产品发布会。下午还有金仓数据库开发者大会。开发者大会设了三个专场。其中一个叫内核能力与智能运维专场。它讲 MAA 高可用架构的 AI 能力也讲智能性能调优和性能自治。还有 KEMCC 运维智能体。官方的说法是推动运维从被动监控升级为 AI 自治。另一个专场讲数据准备智能体、KES 向量检索引擎还有 PL/SQL 到 PL/AI。这些名字背后是同一件事。Agent 不再都待在库外面有的会住进数据库里。它们不是来替人点按钮的是要自己找数据、自己动手。那问题就绕回来了。库外的 Agent我用账号、视图、资源组、审计管着。库里的 Agent 用谁的账号。它能看哪些表。一次自治动作能改多少东西。它的每一步留不留痕。性能调优和自治前提都是先看见现场。执行计划、等待事件、资源占用这些得先拿到。可看见现场本身也是一项权限。所以我不太关心它一次能做多少。我关心它动手之前有没有边界动完有没有记录。一个会自己改参数的 Agent比一个只会查询的 Agent 更需要审计。前者出问题可能连回滚的窗口都没有。发布会给的是方向边界怎么落还要看版本和场景。但有一条我比较确定。Agent 越靠近数据库权限就越不能只靠外面那层应用兜着。边界得往库里挪。对我们用库的人来说能做的事其实没变。账号独立、最小授权、行数上限、超时、审计可归因。这套东西今天就能配上。库里的 Agent 来了只是主语从「我的 Agent」换成「数据库的 Agent」。八、避坑清单给 Agent 的账号别只分读写。要分能看什么、能查多少、能跑多久、出事找谁。只读只是第一层后面还有对象、资源、审计、输入四道门。少一道风险就从那道门进来。别把应用账号借给 Agent。共用账号日志里分不清谁干的出问题也收不回权限。给每个 Agent 单独账号设连接数、超时和行数上限。权限按最小化给用完就收。最后一条是我自己踩的。第一次给 Agent 开账号我图省事直接复用了报表账号。它跑了一条大查询把从库延迟拖到十几分钟。我去查日志满屏都是同一个账号分不清是人还是 Agent。后来才拆出独立账号加了行数上限。现在开账号前我先问三件事看哪张表、查多少行、跑多久。九、写在最后Agent 连数据库风险不在它会不会写。在它会读多少、读多久、把结果带到哪。只读账号只是把写堵住读的门还开着。门开多大要按业务需要量不是按省事。权限边界也不是一次配完。Agent 的能力在变数据在变边界要跟着复查。每月看一遍账号权限、行数上限和审计记录。比出了事再补便宜得多。你们给 AI Agent 开过数据库账号吗是独立账号还是共用踩过什么坑评论区聊聊。我是数据库小学妹帮你少走弯路少踩坑咱们下篇见
阅读完成 · 觉得有帮助?