PostgreSQL 15(取消了stats collector历程)对统计信息收集的改进(译) ...

打印 上一主题 下一主题

主题 791|帖子 791|积分 2383

  1. [/code]stats collector历程是PostgreSQL数据库的统计信息收集器,用来收集数据库运行期间的统计信息,如表的增删改次数,数据块的个数,索引的变化等等。收集统计信息主要是为了让优化器做出正确的判断,选择最佳的实行筹划。
  2. PostgreSQL 15之前的版本中,有一个stats collector后台历程,PostgreSQL 15开始取消了这个历程,那么为什么要取消这个历程,这个历程原本的工作由又怎样完成?
  3. 原文地址:[url=https://www.postgresql.fastware.com/blog/how-postgresql-improved-statistics-collector-in-the-latest-version]https://www.postgresql.fastware.com/blog/how-postgresql-improved-statistics-collector-in-the-latest-version[/url]
  4. 以下为译文
  5.  盛行的开源数据库管理系统 PostgreSQL 的最新版本——PostgreSQL 15,对其统计信息收集器进行了重大改进。这些新变化旨在进步其正确性和服从,从而使数据库管理员更容易监控和优化他们的 PostgreSQL 数据库。统计信息收集器是一个关键模块,负责收集和报告有关数据库性能和使用的各种统计数据。在本文中,我将概述PostgreSQL 15中所做的更改,以及这些更改怎样能够帮助数据库管理员。在PostgreSQL 14及之前的版本中,统计信息收集器通过UDP套接字接收统计信息更新,并定期将这些接收到的统计信息写入暂时文件。这些文件可能会非常大,并且常常在极短的时间内被频繁写入。当添加更多有用的统计信息时,这可能会成为瓶颈。 [size=5]What is the Stats Collector doing in PostgreSQL?[/size]
  6. 统计信息收集器是一个后台历程,负责收集本地服务器上活动的信息,如表和索引的访问环境以及vacuum和analyze活动,它还跟踪每个表中的总行数。别的,它还可以统计用户定义函数的调用次数以及每个函数所花费的总时间。统计信息收集器收集的信息可以通过各种pg_stat_和pg_statio_视图来获取。
  7. 以下是与统计信息收集器相关的参数:
  8. [list]
  9. [*]track_activities
  10. [*]track_activity_query_size
  11. [*]track_counts
  12. [*]track_functions
  13. [*]track_io_timing
  14. [*]track_wal_io_timing
  15. [*]stats_temp_directory
  16. [*]stats_fetch_consistency (from PostgreSQL 15 onwards)
  17. [/list]如果我们比较PostgreSQL 14和15的默认后台历程列表,可以很容易地发现统计信息收集器后台历程并未出现在PostgreSQL 15的列表中。
  18. On PostgreSQL-15
  19. [code][root@localhost opt]# ps -ef | grep postgres
  20. postgres 4942       0 08:43 ?      00:00:00 /usr/pgsg1-15/bin/postgres -D /opt/PGSQL15
  21. postgres 4943  4942 0 08:43 ?      00:00:00 postgres: logger
  22. postgres 4944  4942 0 08:43 ?      00:00:00 postgres: checkpointer
  23. postgros 4945  4942 0 08:43 ?      00:00:00 postgres: background writer
  24. postgres 4947  4942 0 08:43 ?      00:00:00 postgres: walwriter
  25. postgros 4948  4942 0 08:43 ?      00:00:00 postgres: autovacuum launcher
  26. postgres 4949  4942 0 08:43 ?      00:00:00 postgres: logical replication launcher
  27. root    14523 13927 0 21:59 pts/2  00:00:00 grep --color=auto postgres
  28. [root@localhost opt]#
复制代码
On PostgreSQL-14
  1. [root@localhost opt]# ps -ef | grep postgres
  2. postgres 14641 1 0 22:01 ?      00:00:00 /usr/pgsg1-14/bin/postgres -D /opt/PGSQL14
  3. postgres 14642 14641 0 22:01 ?      00:00:00 postgres: logger
  4. postgres 14644 14641 0 22:01 ?      00:00:00 postgres: checkpointer
  5. postgros 14645 14641 0 22:01 ?      00:00:00 postgres: background writer
  6. postgres 14646 14641 0 22:01 ?      00:00:00 postgres: walwriter
  7. postgros 14647 14641 0 22:01 ?      00:00:00 postgres: autovacuum launcher
  8. postgres 14648 14641 0 22:01 ?      00:00:00 postgres: stats collector
  9. postgres 14649 14641 0 22:01 ?      00:00:00 postgres: logical replication launcher
  10. root     14678 13927 0 22:01 pts/2  00:00:00 grep --color=auto postgres
  11. [root@localhost opt]#
复制代码
 
Challenges for statistics collection up to PostgreSQL 14

众所周知,PostgreSQL采用简单的“每用户一历程”的客户端/服务器模型。因此,PostgreSQL中会话的每个后端都是一个独立的历程。想象一下,如果每个后端会话都要收集统计信息并将其传输出去,这可不是一项简单的任务,因为每个后端都需要向单个统计信息收集器历程发送它们所实行活动的信息(每个后台历程将他们的活动信息发送给单独的“stats collector”历程。通过UDP包进行通信)。正如我上面提到的,PostgreSQL会使用UDP套接字来进行这种通信。
很天然地,我们可以感觉到这种方法存在很多题目。我信赖你们中的很多人都碰到过类似这样的题目:

  • LOG: 使用过时的统计数据而不是当前的统计数据,因为统计数据收集器没有相应
  • Autovacuum 工作服从降低
  • 高I/O行为
如果你设置了恰当的日志级别,你可以在PostgreSQL 14日志中看到如下消息:
  1. 2022-12-19 23:22:03.338 +08 [14641] LOG: parameter "log_min_messages" changed to "debug3"
  2. 2022-12-19 23:22:03.341 +08 [14644] DEBUG: checkpointer updated shared memory configuration values
  3. 2022-12-19 23:22:03.343 +08 [14648] DEBUG: received inquiry for database 0
  4. 2022-12-19 23:22:03.343 +08 [14648] DEBUG: writing stats file "pg_stat_tmp/global.stat"
  5. 2022-12-19 23:22:03.344 +08 [14648] DEBUG: writing stats file "pg_stat_tmp/db_0.stat"
  6. 2022-12-19 23:23:03.406 +08 [14648] DEBUG: received inquiry for database 0
  7. 2022-12-19 23:23:03.406 +08 [14648] DEBUG: writing stats file "pg_stat_tmp/global.stat"
  8. 2022-12-19 23:23:03.406 +08 [14648] DEBUG: writing stats file "pg_stat_tmp/db_0.stat"
  9. 2022-12-19 23:23:03.418 +08 [16112] DEBUG: InitPostgres
  10. 2022-12-19 23:23:03.419 +08 [16112] DEBUG: autovacuum: processing database "postgres"
  11. 2022-12-19 23:23:03.419 +08 [14648] DEBUG: received inquiry for database 14486
  12. 2022-12-19 23:23:03.419 +08 [14648] DEBUG: writing stats file "pg_stat_tmp/global.stat"
  13. 2022-12-19 23:23:03.419 +08 [14648] DEBUG: writing stats file "pg_stat_tmp/db_14486.stat"
  14. 2022-12-19 23:23:03.419 +08 [14648] DEBUG: writing stats file "pg_stat_tmp/db_0.stat"
复制代码
上述消息表明,统计信息收集器历程将统计数据写入暂时文件,由于需要频繁收集信息(stats collector通过UDP接收统计更新,并通过定期将统计数据写入暂时文件来共享统计数据。这些文件可以达到数十兆字节,并且每秒最多写入2次),这会导致大量的I/O操作。在高负载期间,这可能会导致出现“LOG: using stale statistics instead of current ones because stats collector is not responding”的消息。为了办理这个题目,强烈建议将pg_stat_tmp挂载到基于RAM的文件系统上。为此,需要有用配置stats_temp_directory参数,将其设置为基于RAM的文件系统路径。
在大多数系统上,stats_temp_directory的默认位置仅在数据目录内。

Statistics collection improvement in PostgreSQL 15


让我们看看社区在PostgreSQL 15中做出了哪些更改。
如前所述,在PostgreSQL 14及之前的版本中,统计信息收集器使用文件系统来写入统计数据,但从PostgreSQL 15开始,社区转而使用动态共享内存。现在,采用这种方法后,就不再需要设置stats_temp_directory了,但为了支持像pg_stat_statements这样的扩展功能,仍然会保存一个空的pg_stat_tmp目录。
在PostgreSQL 15的新改进中,所有统计数据的更改最初都会在每个历程中以“待处置惩罚”状态本地收集。这里的“待处置惩罚”意味着统计数据已经被收集,但尚未被输入到共享统计系统中。稍后,在提交后不久或通过超时机制,它们将被刷新到共享内存中。现在就出现了怎样管理这些统计数据的检索的题目。因此,社区引入了一个名为stats_fetch_consistency的新选项来解答这个题目。
当在事务中多次检索累积统计数据时,stats_fetch_consistency选项将控制行为方式。该参数有三个可能的选项:none、cache和snapshot。

  • If the value is set to "none," shared memory counts are re-fetched with each access;
       译者注:每次检索统计信息时,都会返回当前可用的最新数据。这可能会导致在事务期间检索到的数据不一致,因为统计信息可能会在事务实行期间被更新。

  • When set to "cache," an object's first access to its statistics is stored there until the transaction is complete, unless pg_stat_clear_snapshot() is performed. This is the default option.
       PostgreSQL会在事务开始时缓存统计信息,并在整个事务期间返回该缓存的数据。这可以确保在事务期间检索到的数据是一致的,但可能会捐躯一些实时性,因为缓存的数据可能不是最新的。

  • If the option is set to "snapshot," all statistics available in the current database are cached at initial access until the transaction is complete, unless pg_stat_clear_snapshot() is performed.
       PostgreSQL会在事务开始时获取一个统计信息的快照,并在整个事务期间返回该快照的数据。这与cache模式类似,但快照提供了更强的一致性保证。快照是在事务开始时创建的,因此它反映了事务开始时的数据库状态。 What happens at restart?

既然你已经阅读了以上内容,一个显而易见的题目是:“如果PostgreSQL重启,会发生什么?”
在这种环境下,PostgreSQL会将统计数据保存在磁盘上pg_stat目录中的一个名为pgstat.stat的文件中。由于检查点历程(checkpointer process)会在关闭之前控制整个统计数据的写入过程,因此在PostgreSQL的启动过程中,这些数据将再次被加载。
译者注:如果是PostgreSQL非正常关闭,也就是checkpoint没来得及将统计信息写入磁盘,重启后统计信息将丢失,参考https://www.percona.com/blog/postgresql-15-stats-collector-gone-whats-new/
  1. PostgreSQL log entries during the Stop event
  2. 2022-12-21 10:39:54.260 +08 [6967] DEBUG: postmaster received signal 2
  3. 2022-12-21 10:39:54.260 +08 [6967] LOG: received fast shutdown request
  4. 2022-12-21 10:39:54.262 +08 [6967] LOG: aborting any active transactions
  5. 2022-12-21 10:39:54.262 +08 [6974] DEBUG: logical replication launcher shutting down
  6. 2022-12-21 10:39:54.263 +08 [6973] DEBUG: autovacuum launcher shutting down
  7. 2022-12-21 10:39:54.267 +08 [6967] LOG: background worker "logical replication launcher" (PID 6974) exited with exit code 1
  8. 2022-12-21 10:39:54.267 +08 [6969] LOG: shutting down
  9. 2022-12-21 10:39:54.270 +08 [6969] LOG: checkpoint starting: shutdown immediate
  10. 2022-12-21 10:39:54.270 +08 [6969] DEBUG: performing replication slot checkpoint
  11. 2022-12-21 10:39:54.276 +08 [6969] DEBUG: checkpoint sync: number=1 file=pg_multixact/offsets/0000 time=0.715 ms
  12. 2022-12-21 10:39:54.276 +08 [6969] DEBUG: checkpoint sync: number=2 file=pg_xact/0000 time=0.582 ms
  13. 2022-12-21 10:39:54.279 +08 [6969] DEBUG: attempting to remove WAL segments older than log file 000000000000000000000002
  14. 2022-12-21 10:39:54.279 +08 [6969] DEBUG: SlruScanDirectory invoking callback on pg_subtrans/0000
  15. 2022-12-21 10:39:54.279 +08 [6969] LOG: checkpoint complete: wrote 3 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write
  16. =0.001 s, sync=0.002 s, total=0.011 s; sync files=2, longest=0.001 s, average=0.001 s; distance=0 kB, estimate=0 kB
  17. 2022-12-21 10:39:54.279 +08 [6969] DEBUG: writing stats file "pg_stat/pgstat.stat"
  18. 2022-12-21 10:39:54.281 +08 [6967] DEBUG: cleaning up orphaned dynamic shared memory with ID 3552075372
  19. 2022-12-21 10:39:54.281 +08 [6967] DEBUG: cleaning up dynamic shared memory control segment with ID 2802447064
  20. 2022-12-21 10:39:54.283 +08 [6967] LOG: database system is shut down
  21. 2022-12-21 10:39:54.288 +08 [6968] DEBUG: logger shutting down
复制代码
PostgreSQL log entries during the Start event
  1. 2022-12-21 10:39:54.409 +08 (6994) LOG: starting PostgreSQL 15.1 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat
  2. 4.8.5 4.8.5-44), 64-bit
  3. 2022-12-21 10:39:54.410 +08 (6994) LOG: listening on IPv6 address "::1", port 5432
  4. 2022-12-21 10:39:54.410 +08 (6994) LOG: listening on IPv4 address "127.0.0.1", port 5432
  5. 2022-12-21 10:39:54.412 +08 [6994) LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
  6. 2022-12-21 10:39:54.415 +08 [6994] LOG: listening on Unix socket "/tmp/.s.PGSQL.5432"
  7. 2022-12-21 10:39:54.418 +08 (6996) DEBUG: checkpointer updated shared memory configuration values
  8. 2022-12-21 10:39:54.420 +08 (6998) LOG: database system was shut down at 2022-12-21 10:39:54 +08
  9. 2022-12-21 10:39:54.420 +08 (6998) DEBUG: checkpoint record is at 0/30E1708
  10. 2022-12-21 10:39:54.420 +08 (6998] DEBUG: redo record is at 0/30E1708; shutdown true
  11. 2022-12-21 10:39:54.420 +08 [6998] DEBUG: next transaction ID: 4667; next DID: 16414
  12. 2022-12-21 10:39:54.420 +08 (6998) DEBUG: next MultiXactId: 1; next MultiXactOffset: 0
  13. 2022-12-21 10:39:54.420 +08 (6998) DEBUG: oldest unfrozen transaction ID: 717, in database 1
  14. 2022-12-21 10:39:54.420 +08 (6998) DEBUG: oldest MultiXactId: 1, in database 1
  15. 2022-12-21 10:39:54.420 +08 (6998] DEBUG: commit timestamp Xid oldest/newest: 0/0
  16. 2022-12-21 10:39:54.420 +08 [6998] DEBUG: transaction ID wrap limit is 2147484364, limited by database with OID 1
  17. 2022-12-21 10:39:54.420 +08 [6998] DEBUG: MultiXactld wrap limit is 2147483648, limited by database with OID 1
  18. 2022-12-21 10:39:54.420 +08 (6998] DEBUG: starting up replication slots
  19. 2022-12-21 10:39:54.420 +08 (6998) DEBUG: starting up replication origin progress state
  20. 2022-12-21 10:39:54.421 +08 (6998) DEBUG: reading stats file "pg_stat/pgstat.stat"
  21. 2022-12-21 10:39:54.421 +08 (6998] DEBUG: removing permanent stats file "pg_stat/pgstat.stat"
  22. 2022-12-21 10:39:54.422 +08 [6998] DEBUG: MultiXactId Wrap limit is 2147483648, limited by database with OID 1
  23. 2022-12-21 10:39:54.422 +08 (6998] DEBUG: MultiXact member stop limit is now 4294914944 based on MultiXact 1
  24. 2022-12-21 10:39:54.425 +08 (6994) DEBUG: starting background worker process "logical replication launcher"
  25. 2022-12-21 10:39:54.425 +08 (6994) LOG: database system is ready to accept connections
  26. 2022-12-21 10:39:54.426 +08 (7001] DEBUG: logical replication launcher started
  27. 2022-12-21 10:39:54.428 +08 [7000] DEBUG: autovacuum launcher started
复制代码
Before you go

最终,这些新功能通过降低收集统计信息的开销来进步性能。这些增强功能有助于确保随着数据库规模和工作负载的增长,PostgreSQL将继承保持良好的可扩展性和性能。
 
 
 
 
 
原文有一个看起来让人非常放松的mp4,拿了过来
  
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

来自云龙湖轮廓分明的月亮

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表