除了存储在表中的常规数据之外,PostgreSQL中还需要维护某些类型的元数据。例如,如果在 PostgreSQL中使用 MultiXacts 或 NOTIFY,或者有需要保留一段时间的信息(如提交时间戳)。PostgreSQL将此信息存储在磁盘上,作为持久化的数据,但出于性能原因,PostgreSQL还会将其缓存在共享内存的SLRU专用缓存中,因为这些信息通常被频繁访问。
在某些情况下(例如,负载极大的应用程序会生成较长的事务,其中包含大量子事务(频繁的命令调用SAVEPOINT)),该缓存不够大,并且频繁使缓存中的数据失效会导致大量性能损失(和大量的CPU负载)。
所以从 PostgreSQL13 开始,在视图中提供了统计信息pg_stat_slru,有些问题通过这个视图很容易检测到,但是不能从数据库层面进行解决。
postgres<17beta1>(ConnAs[postgres]:PID[28643] 2024-05-31/19:59:31)=# select * from pg_stat_slru;
+------------------+-------------+----------+-----------+--------------+-------------+---------+-----------+-------------------------------+
| name | blks_zeroed | blks_hit | blks_read | blks_written | blks_exists | flushes | truncates | stats_reset |
+------------------+-------------+----------+-----------+--------------+-------------+---------+-----------+-------------------------------+
| commit_timestamp | 0 | 0 | 0 | 0 | 0 | 23 | 0 | 2024-05-28 11:48:07.339976+08 |
| multixact_member | 1 | 0 | 0 | 1 | 0 | 23 | 0 | 2024-05-28 11:48:07.339976+08 |
| multixact_offset | 1 | 1 | 6 | 7 | 0 | 23 | 0 | 2024-05-28 11:48:07.339976+08 |
| notify | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2024-05-28 11:48:07.339976+08 |
| serializable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2024-05-28 11:48:07.339976+08 |
| subtransaction | 9 | 0 | 0 | 7 | 0 | 23 | 23 | 2024-05-28 11:48:07.339976+08 |
| transaction | 2 | 4016 | 6 | 19 | 0 | 23 | 0 | 2024-05-28 11:48:07.339976+08 |
| other | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2024-05-28 11:48:07.339976+08 |
+------------------+-------------+----------+-----------+--------------+-------------+---------+-----------+-------------------------------+
(8 rows)
因此在 PostgreSQL 17 中,允许配置 SLRU 缓存大小 ,把以前的单个缓存分裂成几部分,每部分的缓存,分别对应数据目录下几种持久化的文件。我们可以按需对个别参数进行调整,以解决某些问题,例如,如果你使用了很多 MultiXacts,你可能希望增加multixact_member_buffers。
[postgres@xmaster-PostgreSQL-17beta1-06 ~]$ cd $PGDATA
[postgres@xmaster-PostgreSQL-17beta1-06 data]$ ll
total 68
drwx------ 8 postgres dbgrp 76 May 31 16:22 base
-rw------- 1 postgres dbgrp 24 May 31 16:22 current_logfiles
drwx------ 2 postgres dbgrp 4096 May 31 16:24 global
drwx------ 2 postgres dbgrp 66 May 31 16:22 log
drwx------ 2 postgres dbgrp 6 May 28 11:48 pg_commit_ts
drwx------ 2 postgres dbgrp 6 May 28 11:48 pg_dynshmem
-rw------- 1 postgres dbgrp 5711 May 28 11:48 pg_hba.conf
-rw------- 1 postgres dbgrp 2640 May 28 11:48 pg_ident.conf
drwx------ 4 postgres dbgrp 68 May 31 17:53 pg_logical
drwx------ 4 postgres dbgrp 36 May 28 11:48 pg_multixact
drwx------ 2 postgres dbgrp 6 May 28 11:48 pg_notify
drwx------ 2 postgres dbgrp 6 May 31 17:48 pg_replslot
drwx------ 2 postgres dbgrp 6 May 28 11:48 pg_serial
drwx------ 2 postgres dbgrp 6 May 28 11:48 pg_snapshots
drwx------ 2 postgres dbgrp 6 May 28 20:07 pg_stat
drwx------ 2 postgres dbgrp 6 May 28 11:48 pg_stat_tmp
drwx------ 2 postgres dbgrp 18 May 28 11:48 pg_subtrans
drwx------ 2 postgres dbgrp 6 May 28 11:48 pg_tblspc
drwx------ 2 postgres dbgrp 6 May 28 11:48 pg_twophase
-rw------- 1 postgres dbgrp 3 May 28 11:48 PG_VERSION
drwx------ 4 postgres dbgrp 109 May 31 17:53 pg_wal
drwx------ 2 postgres dbgrp 18 May 28 11:48 pg_xact
-rw------- 1 postgres dbgrp 88 May 28 11:48 postgresql.auto.conf
-rw------- 1 postgres dbgrp 31177 May 28 20:07 postgresql.conf
-rw------- 1 postgres dbgrp 60 May 28 20:07 postmaster.opts
-rw------- 1 postgres dbgrp 84 May 28 20:07 postmaster.pid
这几部分缓存的变量是 commit_timestamp_buffers、multixact_member_buffers、multixact_offset_buffers、notify_buffers、serializable_buffers、subtransaction_buffers 和 transaction_buffers。
- commit_timestamp_buffers对应的持久化文件的路径是pg_commit_ts
- multixact_member_buffers对应的持久化文件的路径是pg_multixact/members
- multixact_offset_buffers对应的持久化文件的路径是pg_multixact/offsets
- notify_buffer对应的持久化文件的路径是pg_notify
- serializable_buffers对应的持久化文件的路径是pg_serial
- subtransaction_buffers对应的持久化文件的路径是pg_subtrans
- transaction_buffers对应的持久化文件的路径是pg_xact
其中,commit_timestamp_buffers、transaction_buffers 和subtransaction_buffers 三个设置成0时,随着shared_buffers自动扩大。三个buffers的大小如果是自动调整,则每1GB共享缓冲区使用2MB,最高可达8MB。
postgres<17beta1>(ConnAs[postgres]:PID[28643] 2024-05-31/19:34:33)=# select name,setting,unit,category,extra_desc,context,vartype,source,min_val,max_val,enumvals,boot_val,reset_val,pending_restart from pg_settings where name like '%buffer%' and name not in('shared_buffers','temp_buffers','vacuum_buffer_usage_limit','wal_buffers','wal_decode_buffer_size');
+--------------------------+---------+------+-------------------------+--------------------------------------------------------------------------+------------+---------+---------+---------+---------+----------
+----------+-----------+-----------------+
| name | setting | unit | category | extra_desc | context | vartype | source | min_val | max_val | enumvals
| boot_val | reset_val | pending_restart |
+--------------------------+---------+------+-------------------------+--------------------------------------------------------------------------+------------+---------+---------+---------+---------+----------
+----------+-----------+-----------------+
| commit_timestamp_buffers | 32 | 8kB | Resource Usage / Memory | Specify 0 to have this value determined as a fraction of shared_buffers. | postmaster | integer | default | 0 | 131072 |
| 0 | 32 | f |
| multixact_member_buffers | 32 | 8kB | Resource Usage / Memory | | postmaster | integer | default | 16 | 131072 |
| 32 | 32 | f |
| multixact_offset_buffers | 16 | 8kB | Resource Usage / Memory | | postmaster | integer | default | 16 | 131072 |
| 16 | 16 | f |
| notify_buffers | 16 | 8kB | Resource Usage / Memory | | postmaster | integer | default | 16 | 131072 |
| 16 | 16 | f |
| serializable_buffers | 32 | 8kB | Resource Usage / Memory | | postmaster | integer | default | 16 | 131072 |
| 32 | 32 | f |
| subtransaction_buffers | 32 | 8kB | Resource Usage / Memory | Specify 0 to have this value determined as a fraction of shared_buffers. | postmaster | integer | default | 0 | 131072 |
| 0 | 32 | f |
| transaction_buffers | 32 | 8kB | Resource Usage / Memory | Specify 0 to have this value determined as a fraction of shared_buffers. | postmaster | integer | default | 0 | 131072 |
| 0 | 32 | f |
+--------------------------+---------+------+-------------------------+--------------------------------------------------------------------------+------------+---------+---------+---------+---------+----------
+----------+-----------+-----------------+
(7 rows)
各个参数详细解释如下:
commit_timestamp_buffers(integer)
指定用于缓存内容的内存量pg_commit_ts。如果指定此值时没有单位,则以块为单位,即BLCKSZ字节,通常为 8kB。默认值为0,请求shared_buffers/512 最多 1024 个块,但不少于 16 个块。此参数只能在服务器启动时设置。
transaction_buffers(integer)
指定用于缓存内容的共享内存量pg_xact。如果指定此值时没有单位,则以块为单位,即BLCKSZ字节,通常为 8kB。默认值为0,请求shared_buffers/512 最多 1024 个块,但不少于 16 个块。此参数只能在服务器启动时设置。
subtransaction_buffers(integer)
指定用于缓存内容的共享内存量pg_subtrans。如果指定此值时没有单位,则以块为单位,即BLCKSZ字节,通常为 8kB。默认值为0,请求shared_buffers/512 最多 1024 个块,但不少于 16 个块。此参数只能在服务器启动时设置。
serializable_buffers(integer)
指定用于缓存内容的共享内存量pg_serial。如果指定此值时没有单位,则以块为单位,即BLCKSZ字节,通常为 8kB。默认值为32。此参数只能在服务器启动时设置。
notify_buffers(integer)
指定用于缓存内容的共享内存量pg_notify。如果指定此值时没有单位,则以块为单位,即BLCKSZ字节,通常为 8kB。默认值为16。此参数只能在服务器启动时设置。
multixact_offset_buffers(integer)
指定用于缓存内容的共享内存量pg_multixact/offsets。如果指定此值时没有单位,则以块为单位,即BLCKSZ字节,通常为 8kB。默认值为16。此参数只能在服务器启动时设置。
multixact_member_buffers(integer)
指定用于缓存内容的共享内存量pg_multixact/members。如果指定此值时没有单位,则以块为单位,即BLCKSZ字节,通常为 8kB。默认值为32。此参数只能在服务器启动时设置。
除此之外,现在除了可以使用select pg_stat_reset_slru(null);函数重置slru的统计数据外,还可以使用pg_stat_reset_shared(NULL)重置所有共享统计数据(包含slru),或者使用pg_stat_reset_shared(‘slru’)重置统slru计数据。而PostgreSQL-16版本及以前,是不支持slru作为pg_stat_reset_shared的参数的。
//PostgreSQL-16不支持pg_stat_reset_shared('slru')
postgres<16.1>(ConnAs[postgres]:PID[225677] 2024-06-03/13:56:48)=# select pg_stat_reset_shared('slru');
ERROR: unrecognized reset target: "slru"
HINT: Target must be "archiver", "bgwriter", "io", "recovery_prefetch", or "wal".
//PostgreSQL-17支持pg_stat_reset_shared('slru')
postgres<17beta1>(ConnAs[postgres]:PID[29209] 2024-05-31/21:26:20)=# select pg_stat_reset_shared('slru');
+----------------------+
| pg_stat_reset_shared |
+----------------------+
| |
+----------------------+
(1 row)




