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

pg_wait_sampling 插件使用手册

最近更新时间:2026-10-21 14:34:31
我的收藏
pg_wait_sampling 用来采样 PostgreSQL 进程的等待事件。它可以看到当前等待、最近一段时间的等待历史,以及累计等待画像。

支持版本

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

插件简介

pg_stat_activity 只能看到当前这一刻的 wait_event。如果问题已经过去,现场就没有了。
pg_wait_sampling 通过后台进程周期性采样等待事件,提供三类数据:
视图
用途
pg_wait_sampling_current
查看当前每个进程在等什么
pg_wait_sampling_history
查看最近一段时间的等待时间线
pg_wait_sampling_profile
查看累计等待画像
常见问题:
数据库慢,是 CPU 忙还是在等锁、等 IO。
某段时间内主要等待事件是什么。
某条 SQL 是否经常等待锁或 IO。

环境准备

配置预加载

pg_wait_sampling 需要共享内存和后台进程,必须预加载。建议同时加载 pg_stat_statements。
shared_preload_libraries = 'pg_stat_statements,pg_wait_sampling'

pg_wait_sampling.history_size = 5000
pg_wait_sampling.history_period = 10
pg_wait_sampling.profile_period = 10
pg_wait_sampling.profile_pid = on
pg_wait_sampling.profile_queries = top
pg_wait_sampling.profile_max_entries = 100000
pg_wait_sampling.sample_cpu = on
修改后重启数据库:
pg_ctl -D $PGDATA restart

创建扩展

CREATE EXTENSION pg_stat_statements;
CREATE EXTENSION pg_wait_sampling;
可以指定 schema:
CREATE SCHEMA pgws;
CREATE EXTENSION pg_wait_sampling SCHEMA pgws;

授权

GRANT pg_monitor TO monitor_user;
普通用户没有 pg_monitor 时,只能看到自己的进程。

常用查询

查看当前等待

SELECT c.pid, a.usename, a.state,
coalesce(c.event_type, 'ON CPU') AS event_type,
coalesce(c.event, 'ON CPU') AS event,
substring(a.query, 1, 80) AS query
FROM pg_wait_sampling_current c
LEFT JOIN pg_stat_activity a ON a.pid = c.pid
ORDER BY c.event_type NULLS LAST;
event_type 为空时表示进程没有等待事件,正在使用 CPU。

查看累计等待画像

SELECT coalesce(event_type, 'ON CPU') AS event_type,
coalesce(event, 'ON CPU') AS event,
sum(count) AS samples,
round(100.0 * sum(count) / sum(sum(count)) OVER (), 2) AS pct
FROM pg_wait_sampling_profile
GROUP BY 1, 2
ORDER BY samples DESC
LIMIT 15;
常见判断:
event_type
说明
ON CPU
进程没有等待,主要在用 CPU
Lock
锁等待
IO
IO 等待
LWLock
内部轻量锁等待
Client
等客户端读写
Timeout
主动等待,例如 pg_sleep

查看最近等待历史

SELECT ts, pid,
coalesce(event_type, 'ON CPU') AS event_type,
coalesce(event, 'ON CPU') AS event,
queryid
FROM pg_wait_sampling_history
WHERE ts > now() - interval '30 seconds'
ORDER BY ts DESC, pid
LIMIT 50;
history 是环形缓冲区,满了会覆盖旧数据。

关联 SQL 文本

SELECT coalesce(p.event_type, 'ON CPU') AS event_type,
coalesce(p.event, 'ON CPU') AS event,
sum(p.count) AS samples,
substring(s.query, 1, 80) AS query
FROM pg_wait_sampling_profile p
LEFT JOIN pg_stat_statements s ON s.queryid = p.queryid
WHERE p.queryid <> 0
GROUP BY 1, 2, 4
ORDER BY samples DESC
LIMIT 15;
需要 pg_stat_statements 正常安装,并且 profile_queries 不为 none。

建立一个观察窗口

SELECT pg_wait_sampling_reset_profile();
-- 等待或运行负载
SELECT pg_sleep(60);
SELECT coalesce(event_type, 'ON CPU'), coalesce(event, 'ON CPU'), sum(count)
FROM pg_wait_sampling_profile
GROUP BY 1, 2
ORDER BY 3 DESC;
pg_wait_sampling_reset_profile() 只能由管理员执行。

函数和视图

对象
说明
pg_wait_sampling_get_current(pid int4)
查看指定进程当前等待,传 NULL 返回全部
pg_wait_sampling_get_history()
返回等待历史环形缓冲区
pg_wait_sampling_get_profile()
返回累计等待画像
pg_wait_sampling_reset_profile()
清空等待画像,仅管理员可执行
pg_wait_sampling_current
当前等待视图
pg_wait_sampling_history
等待历史视图
pg_wait_sampling_profile
等待画像视图

参数说明

参数
默认值
生效方式
说明
pg_wait_sampling.history_size
5000
reload
history 环形缓冲区条数
pg_wait_sampling.history_period
10
reload
history 采样周期,单位毫秒
pg_wait_sampling.profile_period
10
reload
profile 采样周期,单位毫秒
pg_wait_sampling.profile_pid
on
reload
profile 是否按 PID 区分
pg_wait_sampling.profile_queries
top
reload
是否记录 queryid,取值 none、top、all
pg_wait_sampling.profile_max_entries
100000
reload
profile 最大条目数
pg_wait_sampling.sample_cpu
on
reload
是否采样未等待进程
参数是 SIGHUP 级别,修改后执行:
SELECT pg_reload_conf();

常见问题

Q1:查询时提示“必须预加载”怎么办?

A:把 pg_wait_sampling 加入 shared_preload_libraries,然后重启数据库。

Q2:queryid 怎么都是0?

A:检查 pg_wait_sampling.profile_queries 是否为 none;检查是否安装并预加载 pg_stat_statements;检查 pg_stat_statements 是否排在 pg_wait_sampling 前面。

Q3:pid 怎么都是0?

A:说明 pg_wait_sampling.profile_pid = off,所有进程合并统计。需要按进程看时改成 on。

Q4:history 为什么只能回溯很短时间?

A:history 是环形缓冲区。可回溯时间受 history_size、活跃进程数和采样周期影响。可以增大 history_size 或增大 history_period。长期保留建议使用 pg_profile。

Q5:普通用户只能看到自己的数据吗?

A:这是预期行为。需要全量数据时授予 pg_monitor。

Q6:reset 报权限错误是怎么回事?

A:reset 是破坏性操作,只允许管理员执行。

卸载

DROP EXTENSION pg_wait_sampling;
然后从 shared_preload_libraries 中移除 pg_wait_sampling 并重启数据库。
卸载或重启后,history 和 profile 中的内存数据都会丢失。

相关参考