云数据库 PostgreSQL pgsentinel 插件使用手册

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

相关产品
云数据库 PostgreSQL 产品页,含版本规格、价格与购买入口。

一、支持版本

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 = 2048pg_stat_statements.track = allpgsentinel.db_name = 'postgres'pgsentinel_ash.sampling_period = 1pgsentinel_ash.max_entries = 1000pgsentinel_ash.track_idle_trans = offpgsentinel_pgssh.enable = offpgsentinel_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, datnameFROM pg_stat_activityWHERE 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 queryFROM pg_active_session_historyWHERE ash_time > now() – interval '10 minutes'ORDER BY ash_time DESC, pidLIMIT 50;

wait_event_type 为空时表示当时没有等待事件。

八、查看等待分布

SELECT coalesce(wait_event_type, 'ON CPU') AS wait_type, coalesce(wait_event, 'ON CPU') AS wait_event, count(*) AS samplesFROM pg_active_session_historyWHERE ash_time > now() – interval '30 minutes'GROUP BY 1, 2ORDER BY samples DESCLIMIT 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_queryFROM pg_active_session_historyWHERE blockers > 0 AND ash_time > now() – interval '1 hour'ORDER BY ash_time DESCLIMIT 30;

查看阻塞次数最多的进程:

SELECT blockerpid, blocker_state, count(*) AS times_blocking, count(DISTINCT pid) AS victimsFROM pg_active_session_historyWHERE blockers > 0GROUP BY 1, 2ORDER BY times_blocking DESCLIMIT 10;

十、查看活跃时间最多的 SQL

SELECT queryid, cmdtype, count(*) AS active_samples, count(DISTINCT pid) AS sessions, substring(min(query), 1, 80) AS sample_queryFROM pg_active_session_historyWHERE ash_time > now() – interval '30 minutes' AND queryid IS NOT NULL AND queryid <> 0GROUP BY queryid, cmdtypeORDER BY active_samples DESCLIMIT 15;

十一、查看存储过程内部 SQL

SELECT substring(top_level_query, 1, 80) AS top_sql, substring(query, 1, 80) AS inner_sql, cmdtype, count(*) AS samplesFROM pg_active_session_historyWHERE top_level_query IS DISTINCT FROM query AND ash_time > now() – interval '30 minutes'GROUP BY 1, 2, 3ORDER BY samples DESCLIMIT 20;

十二、查看 SQL 统计历史

需要先开启:

pgsentinel_pgssh.enable = on

该参数需要重启。

查询:

SELECT ash_time, queryid, calls, total_exec_time, rows, wal_bytesFROM pg_stat_statements_historyORDER BY ash_time DESCLIMIT 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 统计历史会丢失。

十七、相关参考

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

·pg_profile 插件使用手册

赞 (0)
上一篇 4天前
下一篇 4天前