SQL 时快时慢,PG 19 这个插件彻底解决
PostgreSQL PLAN「复活术」:数据库重启后居然还在?
三个 DBA 的崩溃时刻
凌晨两点,某电商公司的 DBA 小李被报警声惊醒 —— 数据库 CPU 飙升至 98%,业务几乎瘫痪。他迅速定位到一条慢查询,打开 pg_stat_statements 却发现:历史执行计划建议全部消失了。
「就在上周,我还手动调优了 200 多条执行计划建议,全没了。」
这不是个例。在 PostgreSQL 社区,pg_stash_advice 模块因为「重启即丢失」的特性,被吐槽了整整三年( 为了流量, AI在虚构放屁, 这个插件PG19才推出, 随即就有了持久化功能 )。
为什么执行计划建议总在「失忆」?
让我们先理解问题根源。
pg_stash_advice 是 PostgreSQL 的执行计划管理利器 —— 它能存储优化器生成的「执行计划建议」,并在后续查询中自动应用,让你的 SQL 跑得飞快。
但它有一个致命缺陷:所有数据都存在动态共享内存(DSA)中。
数据库重启 → DSA 释放 → 所有建议灰飞烟灭
这意味着什么?每次数据库故障恢复、版本升级、甚至是例行维护重启,你精心调优的几十、上百条执行计划建议全部归零。
破局之道:让数据「落地」
好消息是,这个痛点终于被解决了。
新版本 pg_stash_advice 引入了持久化机制,核心思路很优雅:
将内存中的建议定期写入磁盘文件,重启时自动加载。
实现方式如下:
1. 新增两个 GUC 参数
-- 开启持久化(默认关闭,保持向后兼容)
SET pg_stash_advice.persist = on;-- 写入间隔(默认 30 秒,可根据业务调整)
SET pg_stash_advice.persist_interval = '60s';
2. 后台工作进程自动完成一切
数据库启动时,后台工作进程会自动从 pg_stash_advice.tsv 文件加载历史建议;运行期间,每隔 persist_interval 秒检查是否有变更,有则写入磁盘。
3. 关闭时的「最后一把」
数据库正常关闭时,后台进程会执行最后一次写入,确保数据不丢失。
4. 变更检测:轻量级原子计数器
为了避免不必要的磁盘写入,系统使用 change_count 原子计数器 —— 只有真正发生变更时才触发写入,开销极低。
TSV 文件里长什么样?
好奇的同学可以看一眼实际存储格式(位于 $PGDATA/global/pg_stash_advice.tsv):
stash abc123 1744003200
entry abc123 1744003200 plan_abc SELECT * FROM users WHERE id = $1
entry abc123 1744003200 plan_def SELECT * FROM orders WHERE status = $1
以 stash开头的行:表示一个「存储集合」以 entry开头的行:具体的 advice 条目,包含 ID、时间戳、计划名称和 SQL 模板
实际效果如何?
根据测试数据(新版本夜间压测环境):
结论:零感知接入,原有建议永久保留。
如何升级?
升级路径非常简单:
升级 pg_stash_advice 扩展到新版本 在 postgresql.conf中添加一行:pg_stash_advice.persist = on重启数据库(或等后台进程自动加载)
就这么简单,你的执行计划建议正式开启「穿越重生」模式。
你的数据库还在「断片」吗?
如果你的业务经常遇到数据库重启后性能骤降、慢查询激增的问题,不妨检查一下是否需要 pg_stash_advice + 持久化机制。
你现在用的是哪个版本?有遇到过头疼的「内存丢失」问题吗?
评论区聊聊你的经历,我会逐条回复。觉得这篇文章有用的话,转发给做 DBA 的朋友,一起告别「重启失忆」。