帮你快速理解、总结文档立即下载

pg_profile 插件使用手册

最近更新时间:2026-10-21 14:34:31
我的收藏
pg_profile 用来采集 PostgreSQL 的统计快照,并生成 HTML 性能报告。它适合做日常巡检、问题复盘、上线前后对比和长期趋势分析。

支持版本

PostgreSQL 版本
最早支持版本
插件版本
PostgreSQL 18
v18.6_r1.15
pg_profile 4.10
说明:
本文适用于云数据库 PostgreSQL 18集成版本。

插件简介

PostgreSQL 的很多统计视图是累计值,只能反映从上次 reset 到现在的总量。pg_profile 的做法是定期采样,把统计结果保存到本地历史仓库。生成报告时,它计算两个 sample 之间的差值。
常见用途:
生成某个时间段的 SQL 和数据库性能报告;
对比上线前后性能变化;
保存基线,用于以后对照;
采集多个 PostgreSQL 实例的数据;
结合 pg_stat_kcache、pg_wait_sampling、pgsentinel 展示 CPU、IO、等待事件和 ASH 信息。
pg_profile 本身不需要预加载。它依赖 dblink 作为采集通道。plpgsql 是 PostgreSQL 默认语言,目标库需要已安装。

环境准备

推荐先安装的插件

CREATE EXTENSION pg_stat_statements;
CREATE EXTENSION pg_stat_kcache;
CREATE EXTENSION pg_wait_sampling;
CREATE EXTENSION pgsentinel;
这些插件能让报告内容更完整。缺少其中某个插件时,对应章节会缺失,但 pg_profile 仍可工作。

安装 pg_profile

dblink 通常需要管理员创建:
CREATE EXTENSION dblink;
安装 pg_profile:
CREATE SCHEMA profile;
CREATE EXTENSION pg_profile SCHEMA profile;
说明:
pg_profile 不可迁移,建议创建时就指定好 schema。后续不建议移动 schema。

检查安装

SELECT extname, extversion
FROM pg_extension
WHERE extname = 'pg_profile';

SELECT * FROM profile.show_servers();
默认会创建一个名为 local 的 server。

基本使用

采集快照

SELECT profile.take_sample();
至少需要两个 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。
也可以按时间范围生成:
\\o /tmp/pg_profile_report.html
SELECT profile.get_report('local', tstzrange('2026-09-01 10:00', '2026-09-01 11:00'));
\\o
生成最近两个 sample 的报告:
\\o /tmp/pg_profile_latest.html
SELECT profile.get_report_latest('local');
\\o

生成差异报告

对比两个时间段:
\\o /tmp/pg_profile_diff.html
SELECT profile.get_diffreport('local', 1, 2, 3, 4);
\\o
这类报告适合看上线前后、参数调整前后、优化前后的变化。

切换报告语言

SELECT profile.get_report_locale();
SELECT profile.set_report_locale('zh-CN');
SELECT profile.set_report_locale('en');
内置语言为 en 和 zh-CN。

定时采样

使用系统 cron

*/30 * * * * psql -U postgres -d postgres -c 'SELECT profile.take_sample()' >/dev/null 2>&1
* * * * * psql -U postgres -d postgres -c 'SELECT profile.take_subsample()' >/dev/null 2>&1

使用 pg_cron

如果已安装 pg_cron:
SELECT * FROM profile.create_jobs(
sample_interval => interval '30 minutes',
subsample_interval => interval '1 minute',
ash_subsample_interval => interval '1 minute',
stmt_subsample_interval => NULL
);

SELECT * FROM profile.drop_jobs();
未安装 pg_cron 时,函数会返回跳过信息,不影响手工采样或系统 cron。

基线管理

基线用于长期保留某个 sample 区间。常见场景是上线前、压测前、优化前。
SELECT profile.create_baseline('local', 'before_change', 1, 2, 90);
SELECT * FROM profile.show_baselines('local');
基于基线生成报告:
\\o /tmp/baseline_report.html
SELECT profile.get_report('before_change');
\\o
删除基线:
SELECT profile.drop_baseline('local', 'before_change');

多实例采集

pg_profile 可以在一个库中采集多个 PostgreSQL 实例。远端采集需要先配置连接白名单。
INSERT INTO profile.server_connstr_allowlist(host) VALUES ('db2.example.com');

SELECT profile.create_server(
'db2',
'host=db2.example.com port=5432 dbname=postgres user=profile_collector',
true,
30,
'生产库 db2'
);

SELECT * FROM profile.show_servers();
SELECT profile.take_sample();
连接串安全要求:
不允许写 password=,密码放在 .pgpass。
不允许 URI 形式,例如 postgresql://...。
不允许 service=、hostaddr=。
远端 host 必须先加入 server_connstr_allowlist。

子采样

完整 sample 间隔通常较长。子采样适合抓长查询、长事务和空闲事务。
配置阈值:
SELECT profile.set_server_subsampling(
'local',
true,
interval '10 seconds',
interval '1 minute',
100000,
interval '5 minutes'
);
执行子采样:
SELECT profile.take_subsample();
说明:
take_sample() 不会自动执行普通 take_subsample(),需要单独调度。

SQL 增量采样

用于观察分钟级 SQL 调用趋势。默认关闭。
SELECT profile.set_server_stmt_subsampling('local', true);
SELECT profile.take_stmt_subsample('local');
开启后,报告中会出现 Statement Subsamples 相关内容。

表和索引大小采集

大小采集可能有开销,建议放到低峰时间。
SELECT profile.set_server_size_sampling(
server => 'local',
window_start => '02:00'::timetz,
window_duration => interval '2 hours',
sample_interval => interval '1 day',
collect_mode => 'schedule'
);
collect_mode 可取:
值
说明
off
不主动计算大小
on
每次 sample 都计算
schedule
只在指定时间窗口计算

导出和导入

导出历史数据:
\\copy (SELECT * FROM profile.export_data('local')) TO '/tmp/profile_export.csv' WITH (FORMAT csv)
对外共享时建议脱敏 SQL:
\\copy (SELECT * FROM profile.export_data(server_name => 'local', obfuscate_queries => true)) TO '/tmp/profile_export_obfuscated.csv' WITH (FORMAT csv)
导入到分析库:
CREATE TABLE import_stage (section_id bigint, row_data json);
\\copy import_stage FROM '/tmp/profile_export.csv' WITH (FORMAT csv)
SELECT profile.import_data('import_stage', 'imported_');

参数说明

参数
默认值
说明
pg_profile.topn
20
报告中 TOP N 数量
pg_profile.max_sample_age
7
sample 保留天数
pg_profile.max_query_length
20000
报告中 SQL 文本截断长度
pg_profile.statements_reset
off
采样时是否 reset SQL 统计,生产环境建议保持关闭
pg_profile.track_sample_timings
off
是否记录采样阶段耗时
pg_profile.relsize_collect_mode
off
大小采集模式
pg_profile.subsample_enabled
on
子采样开关
pg_profile.stmt_subsample_retention_hours
168
SQL 增量采样保留小时数
查看当前显式配置:
SELECT current_setting('pg_profile.topn', true),
current_setting('pg_profile.max_sample_age', true),
current_setting('pg_profile.statements_reset', true);
返回 NULL 表示没有显式设置,使用内置默认值。

权限说明

操作
权限要求
执行采样
pg_monitor
生成完整报告
pg_read_all_stats
修改 server、连接串、采样策略
扩展 owner 或管理员
reset 统计
管理员
报告和历史仓库可能包含 SQL 文本、对象名和会话信息。对外导出时建议开启 obfuscate_queries。

常见问题

Q1:创建 pg_profile 报 dblink 权限错误。
A:先由管理员创建 dblink,再创建 pg_profile。
CREATE EXTENSION dblink;
CREATE SCHEMA profile;
CREATE EXTENSION pg_profile SCHEMA profile;
Q2:报 language plpgsql does not exist。
A:目标库缺少 plpgsql。由管理员执行:
CREATE EXTENSION plpgsql;
然后再创建 pg_profile。
Q3:take_sample() 连接失败如何处理?
A:检查 profile.show_servers() 中的连接串、目标库 pg_hba.conf、白名单和 .pgpass。连接串中不能写明文密码。
Q4:报告为空如何处理?
A:报告需要两个 sample 之间的差值。先确认:
SELECT * FROM profile.show_samples();
如果不足两个 sample,再执行一次 take_sample()。
Q5:报告为什么缺少 CPU、等待事件或 ASH 内容?
A:检查目标库是否安装了 pg_stat_kcache、pg_wait_sampling、pgsentinel。缺少插件时,报告对应章节会缺失。
Q6:历史数据为什么变少?
A:可能超过保留期被清理。检查 pg_profile.max_sample_age 和 server 级保留配置。重要时间段建议创建 baseline。
Q7:take_sample() 为什么很慢?
A:开启采样耗时记录:
ALTER SYSTEM SET pg_profile.track_sample_timings = on;
SELECT pg_reload_conf();
SELECT profile.take_sample();
SELECT * FROM profile.v_sample_timings ORDER BY sample_id DESC, time_spent DESC LIMIT 20;
常见原因是大小采集、SQL 条目过多、多 server 串行或远端连接慢。

卸载

卸载前如需保留数据,先导出:
\\copy (SELECT * FROM profile.export_data('local')) TO '/tmp/profile_export.csv' WITH (FORMAT csv)
DROP EXTENSION pg_profile;
如果不再使用 dblink,确认无其它依赖后再删除:
DROP EXTENSION dblink;
说明:
DROP EXTENSION pg_profile 会删除本地历史仓库。

相关参考