帮你快速理解、总结文档立即下载
文档中心>云数据库 PostgreSQL>操作指南>插件管理>可观测性插件>PostgreSQL 可观测性插件套件使用手册

PostgreSQL 可观测性插件套件使用手册

最近更新时间:2026-10-21 14:34:31
我的收藏
本文介绍云数据库 PostgreSQL 18中的可观测性插件套件。套件包含 pg_stat_kcache、pg_wait_sampling、pgsentinel、pg_profile,配合 PostgreSQL 自带的 pg_stat_statements 使用。
本文按实际使用顺序说明安装、配置和常见排查方法。

支持版本

PostgreSQL 版本
最早支持版本
插件版本
PostgreSQL 18
v18.6_r1.15
pg_stat_kcache 2.3.1、pg_wait_sampling 1.1、pgsentinel 1.4.1、pg_profile 4.10
说明:
本文以云数据库 PostgreSQL 18集成版本为准。社区同名插件的功能和权限策略可能不同。

插件简介

这套插件分别解决不同问题:
插件
主要用途
常用场景
pg_stat_kcache
统计 SQL 的 CPU、物理读写、缺页、上下文切换
判断一条 SQL 是耗 CPU 还是耗 IO
pg_wait_sampling
采样等待事件,提供当前等待、历史等待和等待画像
判断数据库慢在锁、IO、LWLock 还是 CPU
pgsentinel
保存活动会话历史,提供 ASH 能力
事后回看某个时间点谁在执行、谁被阻塞
pg_profile
周期性快照和 HTML 报告
生成某个时间段的性能报告、做上线前后对比
pg_profile 是报告和历史仓库。前三个插件提供数据,pg_profile 负责采集、保存和生成报告。

环境准备

修改配置

pg_stat_kcache、pg_wait_sampling、pgsentinel 需要预加载。pg_profile 不需要预加载。
在 postgresql.conf 中配置:
shared_preload_libraries = 'pg_stat_statements,pg_stat_kcache,pg_wait_sampling,pgsentinel'

pg_stat_statements.track = all
pg_stat_statements.max = 10000

pgsentinel.db_name = 'postgres'
说明:
pg_stat_statements 必须放在前面,后面的插件需要使用 queryid。
修改后重启数据库:
pg_ctl -D $PGDATA restart

创建扩展

在需要观测的数据库中执行:
CREATE EXTENSION pg_stat_statements;
CREATE EXTENSION pg_stat_kcache;
CREATE EXTENSION pg_wait_sampling;
CREATE EXTENSION pgsentinel;
CREATE EXTENSION dblink;
CREATE SCHEMA profile;
CREATE EXTENSION pg_profile SCHEMA profile;
说明:
pgsentinel 和 dblink 通常需要管理员创建。
pg_profile 依赖 dblink。
pg_profile 建议安装在单独 schema 中,例如 profile。

检查安装结果

SELECT extname, extversion
FROM pg_extension
WHERE extname IN ('pg_stat_statements','pg_stat_kcache','pg_wait_sampling','pgsentinel','dblink','pg_profile')
ORDER BY extname;

快速使用

1. 看数据库主要在等什么

SELECT coalesce(event_type, 'ON CPU') AS event_type,
coalesce(event, 'ON CPU') AS event,
sum(count) AS samples
FROM pg_wait_sampling_profile
GROUP BY 1, 2
ORDER BY samples DESC
LIMIT 10;
如果 ON CPU 多,说明主要在用 CPU;如果 Lock 多,先看锁等待;如果 IO 多,继续看真实读写。

2. 看哪些 SQL 消耗 CPU 或物理 IO

SELECT substring(query, 1, 80) AS query,
round((exec_user_time + exec_system_time)::numeric, 3) AS cpu_sec,
pg_size_pretty(exec_reads) AS phys_read,
pg_size_pretty(exec_writes) AS phys_write
FROM pg_stat_kcache_detail
WHERE top IS TRUE
ORDER BY exec_user_time + exec_system_time DESC
LIMIT 10;

3. 回看最近活动会话

SELECT ash_time, pid, usename, application_name,
coalesce(wait_event_type, 'ON CPU') AS wait_type,
wait_event, substring(query, 1, 80) AS query
FROM pg_active_session_history
WHERE ash_time > now() - interval '10 minutes'
ORDER BY ash_time DESC
LIMIT 20;

4. 生成性能报告

至少采集两个 sample:
SELECT profile.take_sample();
-- 等待一段时间或运行负载
SELECT profile.take_sample();
SELECT * FROM profile.show_samples();
生成报告:
\\o /tmp/pg_profile_report.html
SELECT profile.get_report('local', 1, 2);
\\o
将 1、2 换成实际 sample id。

排查思路

数据库突然变慢

1. 先用 pg_wait_sampling_profile 看等待分布。
2. 如果是 CPU 或 IO,再用 pg_stat_kcache_detail 找 SQL。
3. 如果是锁等待,再用 pg_active_session_history 找阻塞者。
4. 最后用 pg_profile 对故障时间段生成报告。

上线前后对比

上线前采集两个 sample,上线后再采集两个 sample,然后生成差异报告:
SELECT profile.get_diffreport('local', 1, 2, 3, 4);

需要长期保留某个时间段

为 sample 区间创建 baseline:
SELECT profile.create_baseline('local', 'before_upgrade', 1, 2, 90);
SELECT * FROM profile.show_baselines('local');

权限说明

操作
建议角色
查看全量监控数据
pg_monitor 或 pg_read_all_stats
执行采样
pg_monitor
修改 pg_profile server 配置
pg_profile 扩展 owner 或管理员
reset 统计
管理员
普通用户通常只能看到自己的数据。reset 类操作会清空诊断现场,不能开放给普通监控账号。

常见问题

Q1:创建扩展时报 must be loaded via shared_preload_libraries 怎么办?

A:说明对应 C 插件没有预加载。把插件加入 shared_preload_libraries 后重启数据库。

Q2:视图为空是不是插件没生效?

A:不一定。刚启动、刚 reset 或没有业务负载时都可能为空。也可能是当前用户没有全量权限,只能看到自己的数据。

Q3:pg_profile 报连接失败怎么办?

A:检查 profile.show_servers() 中的连接串。远端连接需要加入 profile.server_connstr_allowlist,连接串中不要写明文密码。

Q4:报告很大怎么办?

A:生成 HTML 时使用 psql -qAt -o report.html,不要用默认表格输出。可适当降低 pg_profile.topn 或缩短保留时间。

卸载

建议按依赖顺序卸载:
DROP EXTENSION pg_profile;
DROP EXTENSION pg_stat_kcache;
DROP EXTENSION pg_wait_sampling;
DROP EXTENSION pgsentinel;
DROP EXTENSION pg_stat_statements;
DROP EXTENSION dblink;
然后从 shared_preload_libraries 中移除 C 插件并重启数据库。
说明:
DROP EXTENSION pg_profile 会删除本地历史仓库。需要保留数据时,先使用 profile.export_data() 导出。

相关参考