pg_stat_kcache ——跟踪cpu、文件系统真实读写行为

326 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路


PostgreSQL中一般建议将shared_buffer值设置成物理内存的1/4,而是要给OS的cache/buffer以足够的空间,从而达到最佳的系统性能。

因此我们通过使用buffer io, shared buffer的统计信息很容易判断错误。为什么呢?假如我们的shared_buffer设置的过小,那么在统计信息中我们发现SQL的shared_buffer命中率很低,很可能该SQL的read都发生在操作系统的cache buffer中,而并没有进行disk io,因为这些行为是file system接口来完成的, 所以数据库内核并不知情。

pg_stat_kcache插件可以为我们避免这一问题,可以更真实的分析出SQL消耗的性能。

安装:
下载地址:
github.com/powa-team/p…

将下载好的安装包解压后直接安装即可。

然后需要加载动态库:
shared_preload_libraries = ‘pg_stat_statements,pg_stat_kcache’

pg_stat_kcache总共提供了三个GUC参数:

  • pg_stat_kcache.linux_hz:补偿采样错误,默认-1
  • pg_stat_kcache.track:跟踪什么类型的SQL,默认是top,比如SQL是调用的function,还有all跟踪所有和none不跟踪
  • pg_stat_kcache.track_planning:是否跟踪planning的操作和持续时间(需要Version ≥13)

安装完成后我们可以通过pg_stat_kcache和pg_stat_kcache_detail这两个视图来进行查看。
pg_stat_kcache提供的是整体运行状况的视图,而pg_stat_kcache_detail则是细化到语句级。

bill@bill=>select * from pg_stat_kcache limit 1;
-[ RECORD 1 ]----+---------------------
datname          | bill
plan_user_time   | 0
plan_system_time | 0
plan_minflts     | 0
plan_majflts     | 0
plan_nswaps      | 0
plan_reads       | 0
plan_reads_blks  | 0
plan_writes      | 0
plan_writes_blks | 0
plan_msgsnds     | 0
plan_msgrcvs     | 0
plan_nsignals    | 0
plan_nvcsws      | 0
plan_nivcsws     | 0
exec_user_time   | 0.018796999999999994
exec_system_time | 0.008628000000000004
exec_minflts     | 865
exec_majflts     | 0
exec_nswaps      | 0
exec_reads       | 253952
exec_reads_blks  | 31
exec_writes      | 0
exec_writes_blks | 0
exec_msgsnds     | 0
exec_msgrcvs     | 0
exec_nsignals    | 0
exec_nvcsws      | 62
exec_nivcsws     | 5

这里我们主要说明下plan_minflts和plan_majflts这两个字段的含义。

  • plan_minflts:生成执行计划时minor page fault次数。
  • plan_majflts:生产执行计划时major page fault次数。

这里简单说明下minor page fault和major page fault的区别。

page fault缺页异常分为两种类型,一种叫做major page fault,这种类型的缺页可以通过 Disk IO来满足,另一种叫做minor page fault,这种缺页可以直接利用内存中的缓存页满足。

如果访问一个地址时,与该地址空间虚拟内存绑定的数据还存在于Disk上,那么此时即会触发一次major fault;如果访问一个地址时,与之绑定的虚拟内存对应的地址空间已经被内核加载到了Page Cache中,那么此时只需要把该Page映射到虚拟内存中即可,这种异常即为一次minor fault。

我们可以直接使用下面的SQL来查看数据库中最消耗CPU的语句:

select * from pg_stat_kcache_detail order by exec_user_time desc limit 1;