mcpField
P
PG Bloat Detective

PG Bloat Detective

本地服务
github.com数据库02 周前更新

关于 PG Bloat Detective

PG Bloat Detective 是面向 DBA 的 PostgreSQL 只读分析工具。它结合表和索引诊断结果、阻塞证据与时间线,并提供 CLI、仪表板和监控指标。

主要功能

  1. 01提供表膨胀诊断及证据
  2. 02识别阻塞 VACUUM 的会话
  3. 03检查索引膨胀和未使用索引
  4. 04使用 SQLite 保存快照时间线
  5. 05生成 HTML 报告和仪表板
  6. 06导出 Prometheus 与 Grafana 指标

适用场景

  1. 01查找阻止 VACUUM 的会话
  2. 02判断表何时需要重写
  3. 03识别可能需要 REINDEX 的索引
  4. 04跟踪多个快照间的膨胀变化

MCP 相关

其 MCP 服务提供 5 个只读工具,用于检查膨胀、收集快照、查看时间线与阻塞者,以及通过一次性快照诊断数据库。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"r69shabh-pg-bloat-detective": {
"command": "uvx",
"args": [
"pg-bloat-detective"
],
"env": {
"BLOAT_DSN": "<BLOAT_DSN>",
"BLOAT_DB": "<BLOAT_DB>"
}
}
}
}
启动命令uvx pg-bloat-detective
需要配置的环境变量
BLOAT_DSNPostgres DSN (read-only enforced: 5s statement timeout, read-only tx)
BLOAT_DBSQLite timeline file written by bloatdetective collect

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypipg-bloat-detective0.1.6

工具

5

收录的工具列表 · 更新于 2 周前

参数类型必填说明
dbstring否

详细介绍

pg-bloat-detective — PostgreSQL 膨胀检查器、VACUUM 阻塞查找器和索引膨胀检测器

查明 PostgreSQL 数据库膨胀的原因、谁在阻塞 VACUUM,以及哪些索引需要 REINDEX——只读操作,并提供证据。 vacuum-starved · blocked-by-idle-xact · needs-rewrite · index-bloated · index-unused — 每个表/索引给出一个判定,并附上 PID 和查询证据。

mcp-name: io.github.r69shabh/pg-bloat-detective

PyPI MCP Registry License: MIT Tests

pip install pg-bloat-detective · 支持 Docker · 适用于 Claude/Cursor 的 MCP 服务 · Prometheus + Grafana · Next.js 仪表板

pip install pg-bloat-detective          # or: pip install -e ".[dev]" from source
python -m bloatdetective collect --db timeline.db   # read-only snapshot (5s timeout)
python -m bloatdetective analyze --db timeline.db   # verdicts + evidence
python -m bloatdetective report --db timeline.db --html --out report.html
bloat-mcp                              # MCP server (stdio) for Claude Desktop / Cursor

这是一个什么工具

一个 PostgreSQL 膨胀分析工具,可以回答其他工具无法解答的三个问题:

  1. 这个表是否膨胀了?原因是什么? — 死元组时间线(pg_stat_user_tables)+ pgstattuple_approx 精确确认。判定结果:normal(保持现状)、vacuum-starved(autovacuum 跟不上)、blocked-by-idle-xact|slot|prepared|active-xact(列出持有 backend_xmin 的 PID 和查询)、needs-rewrite(近似死元组比例 >30%,VACUUM 无法回收)。

  2. 谁在阻塞 VACUUM / autovacuum? — 按快照追踪最早的 backend_xmin 持有者:PID、事务时长、查询文本、过期复制槽、预备事务。处理优先级:prepared-xact > stale-slot > idle-in-transaction。结束一个会话,执行 VACUUM,即可完成。

  3. 索引是否膨胀了?(VACUUM 永远无法修复这个问题) — 对 1GB 成本限制内的索引运行精确 pgstatindex(可通过 --max-bytes 调整,使用 --allow-large 覆盖限制),指标为 100 − avg_leaf_density。超过 30% → index-bloated,安排 REINDEX。所有快照中的扫描次数均为 0 → index-unused,可考虑 DROP。这正是 pganalyze 承认的功能缺口,也是我们的差异化优势,已在实际环境中验证:REINDEX 后从 83.7% 降至 9.9%,而 VACUUM 毫无作用。

一个 SQLite 文件 = 完整时间线。一个静态页面 = 整个事件的全貌。生产环境无需部署 Agent,不执行写入(只读事务,语句超时 5s),适用于 RDS / Neon / Supabase / 自托管的 PG 12–17。

快速上手(60 秒演示)

docker compose up -d
pip install -e ".[dev]"
python -m bloatdetective collect --db timeline.db   # snapshot prod (read-only)
python workload/churn.py --mode idle-xact --secs 60 &  # create the failure
python -m bloatdetective collect --db timeline.db
python -m bloatdetective report --db timeline.db --html --out report.html
python -m bloatdetective serve --db timeline.db &   # :9187/metrics for Prometheus
pytest
bash scripts/benchmark.sh   # full before/after proof -> REPORT.md

判定结果(请按指示操作)

堆:normal(状态稳定,保持现状)· vacuum-starved → 运行 VACUUM / 调整 autovacuum · blocked-by-idle-xact|slot|prepared|active-xact → 结束指定会话,然后运行 VACUUM · needs-rewrite → 使用 pg_repack / VACUUM FULL。 索引:index-bloated(pgstatindex 膨胀率 >30% → 需要 REINDEX,VACUUM 无法修复)· index-unused(各快照中的 idx_scan=0 → 可考虑 DROP,先用 pg_stat_statements 确认)。

索引膨胀是我们的差异化优势(pganalyze 承认存在此功能缺口):collect 只对 1GB 成本限制内的索引运行精确 pgstatindex(可通过 --max-bytes 调整,使用 --allow-large 覆盖限制),指标 = 100 − avg_leaf_density。导出为 pgbloat_index_bloat_pct / pgbloat_index_scans,在 shadcn 仪表板中绘制图表, 也可在 Grafana 中绘制图表。

基准测试(2026-10-05 测量,使用本地 PG16——堆 + 索引,刚刚运行的实时测试)

30s 持续变更,无阻塞者(只是 autovacuum 跟不上)→ VACUUM ANALYZE + REINDEX:

时刻pg_stat 死元组数近似死元组比例索引膨胀率(密度)判定结果
修复前5,108,201—(单次快照滞后)41.9%vacuum-starved + index-bloated churn_pkey
修复后00.0%9.9%normal — 状态稳定,保持现状

此前未解决的问题现已解决:索引膨胀率为 83.7%(密度 16.3),运行 REINDEX 后降至 9.9%(密度 90.1)——单独运行 VACUUM 永远无法处理这个问题。完整日志见 REPORT.md,可视化报告见 report.html。

详细的 3 周计划和竞品差距请参阅 PLAN.md。

MCP 服务(Claude Desktop / Cursor / any MCP client)

5 个工具,以只读方式访问 Postgres(语句超时 5s,只读事务)。bloat_check 会针对每个表/索引返回判定 + 证据 + 修复方案;bloat_live_diagnose 会对一个 临时数据库进行快照,因此绝不会触碰你的时间线文件,是生产环境 DSN 最安全的选择。

pip install pg-bloat-detective   # pulls mcp + psycopg
bloat-mcp                        # stdio transport (also: docker run -i pg-bloat-detective)

Claude Desktop(~/Library/Application Support/Claude/claude_desktop_config.json):

{"mcpServers": {"bloat-detective": {
  "command": "/abs/path/pg-bloat-detective/.venv/bin/python",
  "args": ["-m", "bloatdetective.mcp_server"],
  "env": {"BLOAT_DSN": "dbname=bloatdemo user=postgres host=localhost port=5433",
          "BLOAT_DB": "/abs/path/pg-bloat-detective/timeline.db"}}}}
工具Agent 会获得什么
bloat_check每个表/索引的判定 + 证据 + 操作
bloat_collect时间线快照,返回最新判定
bloat_timeline死元组/近似值/索引膨胀序列 — 起始时间
bloat_blockerspid + 查询 + xmin 年龄 + slot — 应终止哪个会话
bloat_live_diagnose一次性临时快照、诊断并丢弃

公开列表:官方 MCP Registry(io.github.r69shabh/pg-bloat-detective) · mcp.so · awesome-mcp-servers(数据库)。

接口

  • CLI — collect | analyze | report [--html|--json] | serve [--port](本 README 的快速入门)。
  • Dashboard — dashboard/ 中的 Next.js 单事件卡片(report --json 为 data.json 提供数据):判定横幅、死元组 + 索引膨胀图表、阻塞项 + 发现项表格。
  • Prometheus + Grafana — serve 提供 :9187/metrics(pgbloat_dead_tuples、pgbloat_approx_dead_pct、pgbloat_index_bloat_pct、pgbloat_index_scans、pgbloat_xmin_holder_age_seconds);grafana/ 中包含仪表板 JSON + 配置,docker-compose.yml 连接 pg → exporter → Prometheus → Grafana。
  • Docker — Dockerfile 通过 stdio 运行 MCP 服务(docker run -i);compose 会添加演示数据库 + 可观测性技术栈。

常见问题(用户实际会这样搜索)

  • "postgres table bloated how to check" → 运行两次 collect,analyze 会打印判定 + 死/活元组 + 证据。needs-rewrite 表示需要 pg_repack/VACUUM FULL;其他情况会先告诉你成本更低的修复方法。
  • "postgres autovacuum not keeping up / dead tuples growing" → vacuum-starved(阈值为 50 + 0.2×live,取自实时 pg_settings)与 blocked-by-*(某个会话固定了 xmin)。时间线图表会显示死元组是在持续增加(情况恶化),还是先激增再归零(先被阻塞,后解除)。
  • "postgres vacuum blocked by idle in transaction" → 我们会指出 PID、查询和 xmin 年龄。执行 SELECT pg_terminate_backend(pid)(或等待其完成),然后运行 VACUUM table。
  • "postgres index bloat check / reindex needed" → index-bloated 会给出精确的 pgstatindex 百分比 — VACUUM 无法修复,只有 REINDEX/pg_repack 可以。我们会使用 pgstattuple_approx 交叉核对过时的 pg_stat 计数器,避免你追查并不存在的问题。
  • "postgres unused indexes find / drop" → index-unused(所有快照中的 idx_scan=0),并提供大小(字节)。用 pg_stat_statements 确认后再执行 DROP。
  • "rds / neon / supabase bloat" → 按设计采用只读方式;只需 pg_stat_* 视图 + 可选的 pgstattuple 扩展。无需超级用户权限,也无需安装 Agent。
  • "pg_bloat_check vs pgstattuple vs pganalyze vs pghero" → 一次性估算工具只能给出百分比;而我们通过一个开源工具提供时间线 + 阻塞项 + 修复方案 + 修复前后验证,涵盖堆和索引。参见 PLAN.md 中的竞品表。

关键词

postgresql bloat · postgres bloat check · pg_bloat_check alternative · vacuum blocked · autovacuum tuning · dead tuples · pgstattuple_approx · index bloat · pgstatindex · reindex needed · unused indexes · idle in transaction · backend_xmin · replication slot lag · prepared transaction · table bloat estimation · postgres dba tools · postgres monitoring prometheus grafana · MCP server postgres · Claude postgres DBA

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。