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

pg_stat_kcache 插件使用手册

最近更新时间:2026-10-21 14:34:31
我的收藏
pg_stat_kcache 用来统计 SQL 在操作系统层面的资源消耗,包括 CPU 时间、物理读写、缺页和上下文切换。它通常和 pg_stat_statements 一起使用。

支持版本

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

插件简介

pg_stat_statements 能看到 SQL 调用次数、耗时和 buffer 统计,但不能说明一条 SQL 到底消耗了多少 CPU,也不能说明是否真的发生了物理磁盘读写。
pg_stat_kcache 补上这部分信息。常见用途:
问题
查看指标
哪条 SQL 最耗 CPU
exec_user_time、exec_system_time
哪条 SQL 有真实物理读写
exec_reads、exec_writes
是否有缺页
exec_minflts、exec_majflts
是否有明显调度争抢
exec_nvcsws、exec_nivcsws
注意:
shared_blks_read 不是物理读,它表示 PostgreSQL shared buffers 未命中。数据可能仍在 OS Page Cache 中。exec_reads 才是文件系统层面的读取字节数。

环境准备

配置预加载

pg_stat_kcache 需要共享内存,必须预加载。pg_stat_statements 要放在它前面。
shared_preload_libraries = 'pg_stat_statements,pg_stat_kcache'
pg_stat_statements.track = all
pg_stat_kcache.track = top
pg_stat_kcache.track_planning = off
修改后重启数据库:
pg_ctl -D $PGDATA restart

创建扩展

CREATE EXTENSION pg_stat_statements;
CREATE EXTENSION pg_stat_kcache;
可以指定 schema:
CREATE SCHEMA pgsk;
CREATE EXTENSION pg_stat_kcache SCHEMA pgsk;

授权

监控账号需要读取全量数据时,授予:
GRANT pg_monitor TO monitor_user;
普通用户没有 pg_monitor 时,只能看到自己的统计。

常用查询

查看最耗 CPU 的 SQL

SELECT substring(query, 1, 80) AS query,
round((exec_user_time + exec_system_time)::numeric, 3) AS cpu_sec,
round(exec_user_time::numeric, 3) AS user_sec,
round(exec_system_time::numeric, 3) AS system_sec,
rolname, datname
FROM pg_stat_kcache_detail
WHERE top IS TRUE
ORDER BY exec_user_time + exec_system_time DESC
LIMIT 10;
user_sec 高通常表示计算多,例如排序、聚合、表达式计算。system_sec 高通常表示系统调用多,例如大量小 IO 或临时文件操作。

查看真实物理读写最多的 SQL

SELECT substring(query, 1, 80) AS query,
pg_size_pretty(exec_reads) AS phys_read,
pg_size_pretty(exec_writes) AS phys_write,
exec_reads_blks, exec_writes_blks
FROM pg_stat_kcache_detail
WHERE top IS TRUE AND exec_reads > 0
ORDER BY exec_reads DESC
LIMIT 10;

对比 shared buffer 未命中和真实物理读

SELECT substring(s.query, 1, 80) AS query,
s.shared_blks_read AS shared_miss_blocks,
pg_size_pretty(k.exec_reads) AS physical_read
FROM pg_stat_kcache() k
JOIN pg_stat_statements s
ON s.queryid = k.queryid
AND s.dbid = k.dbid
AND s.userid = k.userid
AND s.toplevel = k.top
WHERE k.top IS TRUE
ORDER BY k.exec_reads DESC
LIMIT 10;
如果 shared_blks_read 高但 exec_reads 低,说明很多数据命中了 OS Page Cache;如果两者都高,才更像真实磁盘 IO 压力。

查看整库资源消耗

SELECT datname,
round((exec_user_time + exec_system_time)::numeric, 2) AS cpu_sec,
pg_size_pretty(exec_reads) AS phys_read,
pg_size_pretty(exec_writes) AS phys_write,
stats_since
FROM pg_stat_kcache
ORDER BY exec_user_time + exec_system_time DESC;

查看缺页和上下文切换

SELECT substring(query, 1, 80) AS query,
exec_minflts, exec_majflts, exec_nvcsws, exec_nivcsws
FROM pg_stat_kcache_detail
WHERE top IS TRUE
ORDER BY exec_majflts DESC, exec_nivcsws DESC
LIMIT 10;
exec_majflts 持续较高时,要关注宿主机内存压力。exec_nivcsws 高时,要关注 CPU 争抢。

函数和视图

对象
说明
pg_stat_kcache()
原始统计函数,按 queryid、userid、dbid、top 维度输出
pg_stat_kcache_detail
关联 pg_stat_statements 后的明细视图,包含 SQL 文本、库名、用户名
pg_stat_kcache
按数据库聚合的视图
pg_stat_kcache_reset()
清空统计,仅管理员可执行
如果需要精确关联 pg_stat_statements,建议直接使用 pg_stat_kcache(),并显式关联 s.toplevel = k.top。

参数说明

参数
默认值
生效方式
说明
pg_stat_kcache.track
top
SET 或 reload
none 不统计,top 只统计顶层语句,all 包含嵌套语句
pg_stat_kcache.track_planning
off
SET 或 reload
是否统计规划阶段资源
pg_stat_kcache.linux_hz
-1
SET
Linux HZ,默认自动探测
生产环境一般使用 track = top。只有需要分析函数或存储过程内部 SQL 时,才考虑 track = all。

常见问题

Q1:创建扩展时报需要 shared_preload_libraries 怎么办?

A:说明没有预加载。修改 postgresql.conf,把 pg_stat_kcache 加入 shared_preload_libraries,然后重启。

Q2:pg_stat_kcache_detail 为空,但为什么 pg_stat_kcache() 有数据?

A:pg_stat_kcache_detail 需要关联 pg_stat_statements。如果 SQL 已被 pg_stat_statements 淘汰,视图里就看不到。可以调大 pg_stat_statements.max,或直接查 pg_stat_kcache()。

Q3:plan_* 字段为什么都是0

A:默认不统计规划阶段。需要时执行:
SET pg_stat_kcache.track_planning = on;
之后新执行的 SQL 才会有规划阶段统计。

Q4:普通用户看不到别人的统计吗?

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

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

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

卸载

DROP EXTENSION pg_stat_kcache;
然后从 shared_preload_libraries 中移除 pg_stat_kcache 并重启数据库。
卸载或重启后,内存中的累计统计会丢失。

相关参考