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

pgsentinel 插件使用手册

最近更新时间:2026-10-21 14:34:31
我的收藏
pgsentinel 用来保存活动会话历史,也就是 ASH(Active Session History)。它按周期采样 pg_stat_activity,把活跃会话保存到共享内存中。问题发生后,即使会话已经结束,也可以在缓冲区中回看一段时间内的现场。

支持版本

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

插件简介

pg_stat_activity 只能看当前时刻。很多线上问题持续时间很短,等 DBA 登录时,现场已经没有了。
pgsentinel 解决的是这类问题。它可以记录:
采样时间;
会话 PID、用户、数据库、应用名;
会话状态和等待事件;
当前 SQL 和顶层 SQL;
阻塞者数量、阻塞者 PID、阻塞者状态;
长事务、空闲事务相关信息。
典型用途:
回看某个时间点哪些会话在运行;
排查锁等待和阻塞链;
抓取偶发慢 SQL 的真实参数;
分析存储过程内部实际执行的 SQL;
给 pg_profile 提供 ASH 数据。

环境准备

配置预加载

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

track_activity_query_size = 2048
pg_stat_statements.track = all

pgsentinel.db_name = 'postgres'
pgsentinel_ash.sampling_period = 1
pgsentinel_ash.max_entries = 1000
pgsentinel_ash.track_idle_trans = off

pgsentinel_pgssh.enable = off
pgsentinel_pgssh.max_entries = 10000
说明:
pgsentinel.db_name 必须是已经存在的数据库。后台进程会连接这个库。
修改后重启数据库:
pg_ctl -D $PGDATA restart

创建扩展

pgsentinel 需要管理员创建:
CREATE EXTENSION pg_stat_statements;
CREATE EXTENSION pgsentinel;
可以指定 schema:
CREATE SCHEMA ash;
CREATE EXTENSION pgsentinel SCHEMA ash;

授权

GRANT pg_monitor TO monitor_user;
普通用户没有 pg_monitor 时,只能看到自己的会话历史。

常用查询

检查后台进程

SELECT pid, backend_type, application_name, datname
FROM pg_stat_activity
WHERE backend_type = 'pgsentinel'
OR application_name = 'pgsentinel';
如果没有结果,先检查 shared_preload_libraries 和 pgsentinel.db_name。

回看最近活动会话

SELECT ash_time, pid, usename, datname, application_name, state,
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, pid
LIMIT 50;
wait_event_type 为空时表示当时没有等待事件。

查看等待分布

SELECT coalesce(wait_event_type, 'ON CPU') AS wait_type,
coalesce(wait_event, 'ON CPU') AS wait_event,
count(*) AS samples
FROM pg_active_session_history
WHERE ash_time > now() - interval '30 minutes'
GROUP BY 1, 2
ORDER BY samples DESC
LIMIT 15;
因为采样周期固定,samples 可以近似理解为活跃秒数。

查看阻塞链

SELECT ash_time,
pid AS blocked_pid,
usename AS blocked_user,
wait_event_type, wait_event,
blockers, blockerpid, blocker_state,
substring(query, 1, 80) AS blocked_query
FROM pg_active_session_history
WHERE blockers > 0
AND ash_time > now() - interval '1 hour'
ORDER BY ash_time DESC
LIMIT 30;
查看阻塞次数最多的进程:
SELECT blockerpid, blocker_state,
count(*) AS times_blocking,
count(DISTINCT pid) AS victims
FROM pg_active_session_history
WHERE blockers > 0
GROUP BY 1, 2
ORDER BY times_blocking DESC
LIMIT 10;

查看活跃时间最多的 SQL

SELECT queryid, cmdtype, count(*) AS active_samples,
count(DISTINCT pid) AS sessions,
substring(min(query), 1, 80) AS sample_query
FROM pg_active_session_history
WHERE ash_time > now() - interval '30 minutes'
AND queryid IS NOT NULL AND queryid <> 0
GROUP BY queryid, cmdtype
ORDER BY active_samples DESC
LIMIT 15;

查看存储过程内部 SQL

SELECT substring(top_level_query, 1, 80) AS top_sql,
substring(query, 1, 80) AS inner_sql,
cmdtype, count(*) AS samples
FROM pg_active_session_history
WHERE top_level_query IS DISTINCT FROM query
AND ash_time > now() - interval '30 minutes'
GROUP BY 1, 2, 3
ORDER BY samples DESC
LIMIT 20;

查看 SQL 统计历史

需要先开启:
pgsentinel_pgssh.enable = on
该参数需要重启。
查询:
SELECT ash_time, queryid, calls, total_exec_time, rows, wal_bytes
FROM pg_stat_statements_history
ORDER BY ash_time DESC
LIMIT 20;
说明:
pg_stat_statements_history 保存的是 pg_stat_statements 的核心字段快照,不是完整字段快照。

函数和视图

对象
说明
pg_active_session_history()
返回 ASH 环形缓冲区中的记录
pg_active_session_history
ASH 视图
pg_stat_statements_history()
返回 SQL 统计历史
pg_stat_statements_history
SQL 统计历史视图
get_parsedinfo(int)
查看指定 PID 当前解析出的语句,传 -1 表示所有进程

参数说明

参数
默认值
生效方式
说明
pgsentinel.db_name
postgres
重启
后台进程连接的数据库
pgsentinel_ash.sampling_period
1
reload
ASH 采样周期,单位秒
pgsentinel_ash.max_entries
1000
重启
ASH 环形缓冲区条数
pgsentinel_ash.track_idle_trans
off
reload
是否记录 idle in transaction
pgsentinel_pgssh.enable
off
重启
是否采集 SQL 统计历史
pgsentinel_pgssh.max_entries
10000
重启
SQL 统计历史缓冲条数
track_activity_query_size 会影响 SQL 文本长度,也会影响共享内存占用。调大前要估算内存。

常见问题

Q1:创建扩展为什么报权限错误?
A:pgsentinel 需要管理员创建。
Q2:视图为什么一直为空?
A:先确认后台进程存在,再确认有活跃会话。空闲数据库没有 ASH 记录是正常的。还要检查 pgsentinel.db_name 指向的数据库是否存在。
Q3:为什么只能回看很短时间?
A:ASH 存在环形缓冲区中。可回看时长约等于 max_entries / 平均活跃会话数。可以增大 pgsentinel_ash.max_entries,但会占用更多共享内存并需要重启。
Q4:数据库重启后历史为什么没了?
A:这是预期行为。ASH 在共享内存中。需要长期保留时,用 pg_profile 定期采样落盘。
Q5:看不到 idle in transaction 怎么办?
A:需要开启参数 pgsentinel_ash.track_idle_trans,设置该参数的值为 on,设置后 reload 配置即可开始记录这类会话,之后就可以看到 idle in transaction 了。
Q6:普通用户为什么看不到别人的 SQL?
A:这是权限隔离。需要全量视角时授予 pg_monitor。

卸载

DROP EXTENSION pgsentinel;
然后从 shared_preload_libraries 中移除 pgsentinel 并重启数据库。卸载或重启后,共享内存中的 ASH 和 SQL 统计历史会丢失。

相关参考