PostgreSQL 15 stats collector 在取消后是如何实现的原有功能的

时间:2023-02-27 15:11:56


在POSTGRESQL 15 有一个重要的功能去掉了stats collector 在说为什么去掉这个stats collector 的问题前,我们先得弄清出stats collector 到底是一个什么功能。 

首先stats collector 并不是有些同学理解的对于表的 analyze,实际上这个功能统计了表和索引的访问情况,同时也跟踪每个表的行数以及表进行vacuum 和analyze的活动记录,另外在自己的进程中,还可以查看其他进程正在操作的情况,也是通过 stats collector来进行的。

统计信息的收集也有参数可以进行调整,如 track_counts, track_function, track_activities 等都可以打开会关闭,减少或增加统计信息收集的内容,增加或减少系统的负担。

那么与收集信息有关的部分存储在(部分VIEW 并不全)

pg_stat_activity
pg_stat_bgwriter
pg_stat_database
pg_stat_database_conflicts
pg_stat_replication
pg_stat_all_tables
pg_stat_sys_tables
pg_stat_user_tables
pg_stat_all_index
pg_stat_user_indexes
pg_statio_user_tables
pg_statio_sys_tables
pg_statio_all_indexes
pg_statio_user_indexes

通过下面的语句可以查看当前正在工作的
SELECT pg_stat_get_backend_pid(s.backendid) AS procpid,
      pg_stat_get_backend_activity(s.backendid) AS current_query

   FROM (SELECT pg_stat_get_backend_idset() AS backendid) AS s;


PostgreSQL 15 stats collector 在取消后是如何实现的原有功能的


那么说了这么多,在PG15 中为什么要替换了这个功能,那么必然是有问题

才进行替换。

其中潜在的因素是

1 基于PG15 之前的需要收集的信息来自于每个backend 进程,而针对每

个进程的信息的收集不是一个容易完美实现的事情,

2 每个进程需要将信息发送给 stats collector 进程,发送的方式是通

过UDP的方式进行,但基于UDP的方式的路径并不是一个可靠的模式

其中会包含一些问题,如state statistics , stats collector 工作的情况,

autovacuum 工作捕捉的问题。

3  性能的消耗也是一个传统使用 stat statistics 的问题,如

我们可以从下图PG14中查看到,

PostgreSQL 15 stats collector 在取消后是如何实现的原有功能的


DEBUG:   writing stats file "pg_stat_tmp/global.stat"

DEBUG:  writing stats file "pg_stat_tmp/db_0.stat"

DEBUG:  autovacuum: processing database "postgres"

DEBUG:  received inquiry for database 13881

DEBUG:  writing stats file "pg_stat_tmp/global.stat"

DEBUG:  writing stats file "pg_stat_tmp/db_13881.stat"

DEBUG:  writing stats file "pg_stat_tmp/db_0.stat"

相关的存储空间,来存储相关的数据的目录 (介于PG14)

PostgreSQL 15 stats collector 在取消后是如何实现的原有功能的


基于这些问题,PG15 做出了绝大的改造,将原有在文件系统或者文件中

实现的state statistics 实现的方式转移到了 dynamic shared memory 中。


以前,统计数据收集器通过UDP接收统计数据更新,并通过定期将统计数

据写入临时文件来共享统计数据。这些文件可以达到几十兆字节,每秒

写入两次。


现在统计信息存储在共享内存中。变量编号对象的统计信息存储在dshash

散列表中(由动态共享内存支持)。固定编号的统计数据存储在普通共享内

存中。


PostgreSQL 15 stats collector 在取消后是如何实现的原有功能的


* Each statistics kind is handled in a dedicated file:

  70  * - pgstat_archiver.c
  71  * - pgstat_bgwriter.c
  72  * - pgstat_checkpointer.c
  73  * - pgstat_database.c
  74  * - pgstat_function.c
  75  * - pgstat_io.c
  76  * - pgstat_relation.c
  77  * - pgstat_replslot.c
  78  * - pgstat_slru.c
  79  * - pgstat_subscription.c
  80  * - pgstat_wal.c

但是细心的读者可能发现,在POSTGRESQL15的环境中还存在pg_stat_tmp 目录的原因主要还是在于部分基于原有 POSTGRESQL 设计中的一些东西还需要使用这个目录,所以需要保留,而不是POSTGRESQL 本身还在需要这个目录。比如 pg_stat_statement 模块就还需要这个目录来存放文件。
但随着POSTGRESQL 的统计信息在内存中进行工作的情况,统计信息的及时性将被挑战,所以在POSTGRESQL 15 中新添加了一个新的参数,stats_fetch_consistency  这个参数主要的目的是在实现了新功能后,的数据被查询时的信息一致性,总体的值有 none , cache , snapshot, 我们建议使用默认值即可,如果性能有更高的要求,对于数据的准确性要求不高,则使用 none , 如果对于信息的要求性特别高,需要使用性能最差的snapshot

PostgreSQL 15 stats collector 在取消后是如何实现的原有功能的

但是在系统运作的过程中,难免会有系统异常,导致的系统崩溃,而在这样的情况下,统计信息在内存中并不能安全的全部刷新到我们的磁盘系统中,所以如果遇到系统的崩溃则内存中的统计信息会被抛弃掉。

PgStatsDSA Waiting for stats dynamic shared memory allocator access
PgStatsHash Waiting for stats shared memory hash table access
PgStatsData Waiting for shared memory stats data access

另外后续在POSTGRESQL 中出现的基于状态收集的部分的提示有以上三种,如果需要观察相关状态收集的部分,可以关注日志中相关的信息。