前言
大家好,我是 CC,之前我曾写过一个比较简单的一键运维巡检工具:pgcheck,它最早是基于 Bash 和一批历久弥新的祖传 SQL 拼起来的,优点是直接、简单、拿来就能用;缺点也很明显:工程结构比较粗糙,扩展不够优雅,配置方式也不够清爽,而且也可能带来一系列的安全隐患。
最近我对它做了一轮系统性的重构。这次的目标很明确:新增与保留实用巡检 SQL,同时将 pgcheck 从一个 demo/toy 工具,重构成一个更正式、更容易维护、更适合日常使用的项目。
pgcheck 是什么?
pgcheck 是一个轻量级 PostgreSQL 巡检 CLI 工具,面向 DBA、SRE 和数据库工程师。
它主要用于快速查看 PostgreSQL 实例中的常见运行风险,例如:
- 连接和活跃 SQL
- 锁等待和阻塞链路
- 长事务
- VACUUM 和 autovacuum 状态
- 表膨胀、索引膨胀
- 无效索引、低效索引、未使用索引
- XID / MultiXID 回卷风险
- xmin horizon 阻塞来源
- 复制、复制槽、WAL 保留
- 临时文件使用情况
- PostgreSQL 16+ 的 I/O 统计
简单说,它不是为了替代监控系统,而是作为一个现场诊断和日常巡检的小工具。当你登录到一台 PostgreSQL 机器上,想快速知道“这个库现在大概有没有问题”,pgcheck 就是为这种场景准备的。
1 | Commands: |
这次最大的变化:从 Bash 重构为 Go
旧版本主要是 Bash 脚本调 psql 执行 SQL。
新版本已经重构为 Go 项目:
- 单二进制发布,部署更简单
- SQL 文件通过 Go embed 嵌入二进制
- 命令统一注册管理
- 自动检测 PostgreSQL 服务端版本
- psql 可用时优先使用 psql
- 找不到 psql 时可回退到 Go 原生驱动
- 项目结构更清晰,后续扩展更容易
这意味着不再只是“一个脚本集合”,而是开始具备一个正式 CLI 工具该有的样子。
配置方式也变简单了
之前很多参数可以从命令行传,也可以从环境变量传,虽然灵活,但用起来有点散。
新版做了收敛:连接信息、psql 行为、输出风格统一放到 JSON 配置文件中。
例如:
1 | bin/pgcheck --config pgcheck.json dbstatus |
psql 常见参数也可以配置:
quiet对应psql -qtuples_only对应psql -tno_align对应psql -Ano_psqlrc对应psql -Xextra_args用于透传额外psql参数
最大限度得保留 DBA 日常习惯。
整合 postgres-howto 的实践经验
这次重构还有一个重点:把我在另一个项目 postgres-howto in Chinese 中沉淀的一些实用 SQL,逐步整合进 pgcheck。
新增或增强的巡检项包括:
1 | pgcheck xmin_blockers |
这些检查都来自真实运维中比较常见的问题:
- 为什么 VACUUM 回收不了空间?
- 是谁卡住了 xmin horizon?
- 数据库有没有 XID / MultiXID 回卷风险?
- 哪些表需要 ANALYZE?
- 哪些索引长期没用?
- int4 主键是否快用完?
- WAL 为什么一直增长?
- 复制槽是否保留了大量 WAL?
这些问题单独看都不复杂,但真正线上排查时,如果没有现成 SQL,会浪费很多时间。
支持 PostgreSQL 16+ pg_stat_io
PostgreSQL 16 引入了一个非常重要的视图:pg_stat_io。
新版 pgcheck 增加了两个命令:
1 | pgcheck io |
它们可以帮助查看:
- read / write / extend / fsync 次数
- backend / bgwriter / checkpointer / autovacuum 的 I/O 分布
- relation / temp / WAL I/O
- evictions、reuses
- fsync 时间
这对分析 I/O 压力非常有帮助。
比如:
- 到底是谁在写?
- 是 backend 在写,还是 checkpointer 在写?
- autovacuum 是否造成 I/O 压力?
- checkpoint 是否有尖刺?
- temp file 是否过多?
如果连接的是 PostgreSQL 16 以下版本,工具会直接提示:
1 | pg_stat_io is available only in PostgreSQL 16+. |
这也是新版 pgcheck 开始面向新版本 PostgreSQL 能力演进的一个体现。
新增临时文件检测
最近这一版还加入了一个很实用的命令:
1 | pgcheck temp_files |
它会扫描 PostgreSQL 的 pgsql_tmp 目录,并结合 pg_stat_activity,定位当前哪些会话正在使用临时文件。
这类问题在线上很常见:
- 排序数据太大
- Hash Join / Hash Aggregate 溢出
- work_mem 不够
- SQL 执行计划不理想
- 大查询产生临时文件拖慢磁盘
相比只看 pg_stat_database.temp_bytes 这种累计指标,temp_files 更适合做现场定位。
增加权限检查和友好提示
很多 PostgreSQL 巡检 SQL 都需要一定权限。
例如:
pg_stat_activitypg_lockspg_stat_replicationpg_replication_slotspg_ls_dirpg_stat_filepg_ls_waldir
新版增加了:
1 | pgcheck privilege |
用于查看当前用户是否具备必要的监控权限,例如:
- 是否 superuser
- 是否拥有
pg_monitor - 是否拥有
pg_read_all_stats - 是否拥有
pg_read_all_settings - 是否有 replication privilege
- 是否能执行部分监控函数
如果执行巡检时权限不足,工具也会尽量给出更明确的建议,比如:
1 | Recommendation: |
这点很重要。
一个巡检工具不应该只把 PostgreSQL 的报错原样甩给用户,而应该告诉用户“为什么失败,以及应该怎么处理”。
支持 –show-sql 和 –explain
DBA 对巡检工具天然会有一个问题:
“你这个结果是怎么查出来的?”
所以新版支持:
1 | pgcheck table_bloat postgres --show-sql |
--show-sql 会输出实际执行的 SQL。
--explain 会说明这个检查项的判断逻辑。
巡检工具越专业,越应该让使用者知道结果从哪里来。最开始的版本就有读者担心安全隐患,跑的 SQL 是啥都不知道,还敢用在生产中吗?
命令命名也做了统一
旧版本里有些命令偏动词,有些偏缩写,有些命名不够统一。
新版做了一些调整,例如:
1 | vacuum_need -> vacuum_needed |
不过为了兼容旧用户,旧命令名仍然保留为 alias。
也就是说,老习惯还能继续用,新命名则更适合后续长期维护。
README 也重写了
这次顺手把 README 也重写成了中英双语版本。
新版 README 包括:
- 项目介绍
- 安装和构建方式
- 配置文件说明
- psql 参数说明
- 命令列表
- 使用示例
- 项目结构
- 设计说明
- Roadmap
代码只是能不能运行,README 决定别人能不能理解、能不能用起来、能不能参与改进。
总结
这次 pgcheck 的变化,不是简单加几个 SQL,而是一次比较系统的升级:
- 从 Bash 重构为 Go
- 从脚本集合变成正式 CLI 项目
- 配置方式更清晰
- 命令命名更统一
- README 更完整
- 整合 postgres-howto 中的实战 SQL
- 增加 PG16+
pg_stat_io支持 - 增加临时文件检测
- 增加权限检查
- 增加
--show-sql/--explain
最近折腾这么久,这个版本算是我比较满意的一版了。
它依然保持了 pgcheck 最初的定位:简单、直接、高效,不搞复杂平台,不搞重依赖,只做 PostgreSQL 巡检和现场诊断中真正有用的事情。
后续我还会继续补充更多巡检项,也会考虑增加结构化输出、风险等级、以及不同 PostgreSQL 版本的自动化测试。
项目还在继续打磨中,欢迎大家试用、提 issue,也欢迎把你日常运维中觉得好用的 PostgreSQL SQL 分享出来,一起把这个工具做得更实用。