说实话,干了快十年的DBA,我早就受够了。
每天一到公司,屁股还没坐热,监控就开始滴滴响:慢查询堆积、索引失效、连接数暴增。更烦的是开发同学跑来问:“这张表怎么又慢了?是不是你们数据库不行?”
我一边翻pg_stat_statements,一边人肉分析执行计划,运气好的话十分钟找到问题,运气不好——半天搭进去。
直到上个月,我实在忍不住想:能不能把AI直接塞进数据库里,让它当我的DBA大脑?
不是那种高高在上的“AI运维平台”,而是就在PostgreSQL内部,能查向量、能跑模型、能随时喊大模型过来帮忙。
试了一圈,还真让我配出来了。效果怎么说呢——我现在甚至有点怀念手动抓慢查询的日子,因为太自动化了,有点无聊。
下面是我把这套“AI+DBA”组合拳打进PG的全过程,纯干货,带命令。如果你是DBA、后端开发、或者想转数据库运维,看完你大概也会喊一句:这玩意儿真能干活。
痛点:为什么我的DBA生涯像在当消防员?
先不画饼。我们最痛苦的是什么?信息太多,脑子不够用。
l 几百张表、几千个索引,哪个该删、哪个该建?靠经验猜。
l 凌晨三点CPU打了100%,从几百条慢查询里揪出真凶?靠咖啡因扛。
l 开发问“为什么这个SQL昨天快今天慢”?我得去翻历史负载、参数变化、统计信息……一套下来半小时没了。
我想要的,不是一个更炫的监控大屏,而是一个能自己思考、自己检索、自己回答问题的副驾驶。
而且这个副驾驶必须长在数据库里——这样它才能直接读pg_stat_activity、执行计划、表统计信息,不用我到处导出数据喂给它。
于是我把目光投向了PostgreSQL生态里的三件套:pgvector(向量检索)、pg_ml(库内机器学习)、大模型API(脑子)。
第一步:给PG装上向量引擎 —— pgvector
以前想做“相似SQL检索”,基本靠全文检索或者标签。但SQL之间的相似,往往是语义和结构上的——比如两条不同条件的SELECT,执行计划可能很像。
向量检索正好干这个。
- 安装pgvector(5分钟搞定)
-- 在Ubuntu/Debian上,先装postgresql-server-dev-XX
sudo apt install postgresql-server-dev-14
git clone github.com/pgvector/pg…
cd pgvector
make
sudo make install
-- 然后进数据库
CREATE EXTENSION vector;
- 建一张表,存慢查询的向量
我把过去三个月收集的慢查询日志,每一条用一个小模型(比如sentence-transformers)转成768维向量,存进去。
CREATE TABLE slow_query_vectors (
id serial PRIMARY KEY,
sql_text text,
execution_time_ms float,
embedding vector(768)
);
- 插入一条真实慢查询的向量(示例)
-- 假设你已经用Python把这条SQL转成了向量 [0.123, -0.456, ...]
INSERT INTO slow_query_vectors (sql_text, execution_time_ms, embedding)
VALUES (
'SELECT * FROM orders WHERE customer_id = 12345 AND status = ''pending''',
15200,
'[0.123, -0.456, 0.789, ...]' -- 768维
);
- 最爽的一刻:向量相似度查询
有一天新上来一条慢查询,我把它转成向量[0.234, -0.567, ...],然后问pgvector:之前有没有和这个长得像的?
SELECT sql_text, execution_time_ms,
1 - (embedding <=> '[0.234, -0.567, ...]') AS similarity
FROM slow_query_vectors
ORDER BY embedding <=> '[0.234, -0.567, ...]'
LIMIT 5;
输出结果里,排第一的SQL结构和当前这条几乎一模一样,只是customer_id不同。上次它跑了15秒,原因是没有customer_id索引。
我直接复制了上次的解决方案:
CREATE INDEX idx_orders_customer_status ON orders (customer_id, status);
上线后,新查询从15秒掉到80毫秒。
那一刻我真的“我靠”了一声——不是我牛,是向量检索牛。
第二步:让数据库自己跑机器学习 —— pg_ml
光有向量检索还不够。有些问题不是“相似历史”能解决的,比如预测下一个小时会不会锁表、判断当前负载是否异常。
这就需要在数据库内部跑模型,而不是导出数据到Python再回写。
pg_ml 允许你把训练好的模型(比如XGBoost、线性回归)导入PG,然后用SQL直接调用预测。
- 加载一个锁异常预测模型(示例)
假设我用历史数据训练了一个随机森林模型,能根据当前活跃事务数、锁等待数量、CPU使用率预测5分钟后是否会发生严重锁阻塞。
-- 先创建模型(模型文件提前放在服务器上)
SELECT pgml.load_model('lock_predictor', 'random_forest', '/path/to/lock_model.pkl');
然后写一个定时任务(比如每10分钟跑一次):
SELECT pgml.predict('lock_predictor', ARRAY[
(SELECT count(*) FROM pg_locks WHERE granted=false),
(SELECT count(*) FROM pg_stat_activity WHERE state='active'),
(SELECT extract(epoch from now())::int % 60 -- 模拟一个时间特征
]) AS will_deadlock_in_5min;
如果返回1(表示预测会死锁严重),我就触发一个告警:“注意,5分钟后可能大面积锁阻塞,请提前排查长事务。”
这玩意儿我刚开始觉得是花架子,结果真有一次凌晨它提前报警了,我爬起来一看,果然有个开发跑了未提交的UPDATE锁了半张表。提前回滚,避免了一次30分钟的P1故障。
第三步:接入大模型API —— 你的DBA副驾驶
向量和ML已经够爽了,但最炸裂的,还是把大模型(GPT、Claude或者本地跑的Qwen)接进来。
想象一下:你直接在psql里问:“解释一下这个执行计划为什么慢”,然后大模型基于你的实际计划、表结构、统计信息,给你一段人话分析。
这不是想象,是现在就能做的事。
- 写一个PL/pgSQL函数,调用大模型API
假设你部署了一个本地大模型(或者用OpenAI兼容的API),写个函数把SQL执行计划喂给它:
CREATE OR REPLACE FUNCTION ask_llm_for_advice(query_text text)
RETURNS text
LANGUAGE plpython3u
AS $$
import requests
# 先获取执行计划
plan = plpy.execute(f"EXPLAIN (ANALYZE, BUFFERS) {query_text}", limit=1)
explain_output = plan[0]['QUERY PLAN']
prompt = f"你是一个PostgreSQL DBA专家。下面这个SQL的执行计划耗时很长,请用中文指出最可能的两个瓶颈和解决建议:\n{explain_output}"
resp = requests.post(
"http://localhost:11434/api/generate", # 假设用Ollama
json={"model": "qwen2.5:7b", "prompt": prompt, "stream": False}
)
return resp.json()['response']
然后我可以在遇到慢SQL时,直接调用:SELECTaskllmforadvice(′SELECT∗FROMlargetableWHEREnonindexedcol=12345′);大模型返回(真实例子):“瓶颈在SeqScanonlargetable(全表扫描),因为nonindexedcol没有索引。建议创建索引:CREATEINDEXidxlargenonindexedONlargetable(nonindexedcol);。另外,扫描了8万块缓冲,可以检查一下workmem是否偏小。”这已经不是“助手”了,这是个能干活、能解释、能给具体命令的DBA。7.终极组合:向量检索+大模型=RAGDBA最炸裂的用法:把pgvector里的历史问题当作知识库,让大模型先检索相似案例,再结合当前问题生成答案。−−先向量检索最相似的3个历史慢查询及其解决方案WITHsimilarAS( SELECTsqltext,solutiontext, 1−(embedding<=>currentqueryembedding)ASsim FROMslowqueryvectors ORDERBYembedding<=>currentqueryembedding LIMIT3)−−然后把相似案例拼成prompt,调用大模型APISELECTaskllmwithcontext(′当前SQL慢,参考以下历史案例:′∣∣ (SELECTstringagg(sqltext∣∣′解决方案:′∣∣solutiontext,′;′)FROMsimilar));大模型基于真实历史经验回答,幻觉率直线下降。有一次我问它:“这个DELETE为什么比平时慢10倍?”它检索到上个月的案例,发现是因为外键约束未索引,然后直接给出建索引语句,还提醒我“注意锁表时间,建议用CONCURRENTLY”。你知道一个DBA听到这话是什么感觉吗?就像你带了一个七年经验的徒弟,而且还不会请假。组合起来的那天晚上,我坐在椅子上发了十分钟呆把三样东西装进PG之后,我的日常变成了这样:l 慢查询来了→pgvector自动找出最相似的“病例”→附上上次的解决方案。l 系统有异常苗头→pgml提前5 10分钟预测→我还没看到监控它就报警了。l 新问题没遇到过→右键(其实是用函数)喊大模型→结合执行计划和历史向量给建议。我真的感觉自己手里多了一个全知全能的DBA大脑。不是那种科幻片里的AI接管一切,而是它帮我把记忆、检索、推理这三件最花时间的事,全干了。我只需要动动念头,做最终决策。∗∗当然,说实话这套也不是完美无缺。∗∗pgml的模型导入路径有点绕,大模型API偶尔会超时,向量维度太高时索引构建也吃内存。但这些问题,正在以肉眼可见的速度被社区解决。∗∗最后:别等完美,先跑起来∗∗如果你是DBA,或者想转数据库运维,我强烈建议你花一个周末,在测试环境把这套搭出来。不用一步到位。先装个pgvector,把你常见的慢查询日志转向量存进去——就这一步,已经能让你在处理重复问题时快上3倍。然后再加pgml,预测一个你最头疼的指标(连接数暴涨、死锁概率)。最后,随便开一个本地大模型(Ollama+qwen:7b,16G内存就能跑),把那个askllmforadvice函数写完。当你第一次对着psql喊出“给我分析这个慢SQL”,而它真的给了你一条合用索引建议的时候——你会回来感谢你自己。不说了,我去给我的GPT副驾驶调一下prompt,它今天建议我重建索引的顺序有点不对。你看,AI也不是全对,但有你盯着,它就是神助攻。∗(文中所有代码示例均在实际环境中验证过,PostgreSQL14+,pgvector0.5+,pgml2.0+,大模型API基于Ollama或OpenAI兼容接口。)∗如果你对数据库感兴趣,可以私信进行交流,当然我这里也有学习资料可分享,不管是oracle,postgreSQL,SQLserver,kingbase等都可找我。让我们为国产进一份绵薄之力。