20.4. 资源消耗 #
20.4.1. 内存 #
shared_buffers(integer) #设置数据库服务器用于共享内存缓冲区的内存量。默认值通常为 128 兆字节(
128MB),但如果内核设置不支持,则可能更小(在 initdb 期间确定)。此设置必须至少为 128 千字节。不过,要获得良好性能,通常需要远高于该最小值的设置。如果指定值时没有单位,则以块为单位,即BLCKSZ字节,通常为 8kB。(BLCKSZ的非默认值会改变该最小值。)此参数只能在服务器启动时设置。如果专用数据库服务器具有 1GB 或更多内存,
shared_buffers的合理初始值是系统内存的 25%。对于某些工作负载,将shared_buffers设得更大也有效,但由于 PostgreSQL 同时依赖操作系统缓存,将超过 40% 的内存分配给shared_buffers不太可能比更小的值效果更好。将shared_buffers设得更大时,通常还需要相应增加max_wal_size,以便将大量新数据或已修改数据的写入过程分散到更长的时间内。对于内存少于 1GB 的系统,适合使用更小的内存比例,以便为操作系统留出足够空间。
huge_pages(enum) #控制是否为主共享内存区域请求巨型页。有效值是
try(默认)、on以及off。该参数只能在服务器启动时设置。如果huge_pages被设置为try,则服务器将尝试请求巨型页,但是如果失败会退回到默认的方式。如果为on,请求巨型页失败将使得服务器无法启动。如果为off,则不会请求巨型页。当前,只有 Linux 和 Windows 上支持这个设置。在其他系统上这个参数被设置为
try时,它会被忽略。在 Linux 中,它只在shared_memory_type设置为mmap(默认)的时候被支持。巨型页的使用会导致更小的页表以及花费在内存管理上的 CPU 时间更少,从而提高性能。更多有关 Linux 上使用巨型页的细节请见第 19.4.5 节。
巨型页在 Windows 上被称为大页面。要使用大页面,需要为运行 PostgreSQL 的 Windows 用户账号分配“在内存中锁定页面”的用户权限。可以使用 Windows 的组策略工具(gpedit.msc)来分配用户权限“在内存中锁定页面”。为了在命令窗口以独立进程(而不是 Windows 服务)的方式启动数据库服务器,命令窗口必须以管理员身份运行或者禁用用户访问控制(UAC)。当 UAC 被启用时,普通的命令窗口会在启动时收回用户权限“在内存中锁定页面”。
注意这种设置仅影响主共享内存区域。Linux、FreeBSD 以及 Illumos 之类的操作系统也能为普通内存分配自动使用巨型页(也被称为“超级”页或者“大”页面),而不需要来自 PostgreSQL 的显式请求。在 Linux 上,这被称为“transparent huge pages”(THP,透明巨型页)。已知这种特性对某些 Linux 版本上的某些用户会导致 PostgreSQL 的性能退化,因此当前并不鼓励使用它(与
huge_pages的显式使用不同)。huge_page_size(integer) #控制通过 huge_pages 启用巨型页时所使用的页大小。默认值为零(
0)。设置为0时,使用系统默认的巨型页大小。此参数只能在服务器启动时设置。现代 64 位服务器体系结构上常见的页大小包括:
2MB和1GB(Intel 和 AMD),16MB和16GB(IBM POWER),以及64kB、2MB、32MB和1GB(ARM)。关于使用和支持的更多信息,参见第 19.4.5 节。目前只有 Linux 支持非默认设置。
temp_buffers(integer) #设置每个数据库会话用于临时缓冲区的最大内存量。这些是会话本地的缓冲区,仅用于访问临时表。如果指定值时没有单位,则以块为单位,即
BLCKSZ字节,通常为 8kB。默认值为 8 兆字节(8MB)。(如果BLCKSZ不是 8kB,则默认值按比例变化。)可以在单个会话内更改此设置,但必须在该会话首次使用临时表之前更改;此后尝试更改该值,对该会话不会产生影响。会话会按需分配临时缓冲区,上限为
temp_buffers。对于实际不需要很多临时缓冲区的会话,将此参数设得较大时,开销仅为temp_buffers每增加一就多分配一个缓冲区描述符,约为 64 字节。不过,如果实际使用了某个缓冲区,还会为它额外消耗 8192 字节(一般而言为BLCKSZ字节)。max_prepared_transactions(integer) #设置可同时处于“预备”状态的事务的最大数量(见 PREPARE TRANSACTION)。将此参数设为零(默认值)会禁用预备事务功能。此参数只能在服务器启动时设置。
如果不打算使用预备事务,应将此参数设为零,以防意外创建预备事务。如果使用预备事务,通常应将
max_prepared_transactions设为不小于 max_connections 的值,以便每个会话都能有一个待处理的预备事务。运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。
work_mem(integer) #设置查询操作(如排序或 hash 表)在写入临时磁盘文件之前可使用的基础最大内存量。如果未指定单位,则以千字节为单位。默认值为 4 兆字节(
4MB)。请注意,复杂查询可能同时执行多个排序和 hash 操作,每个操作在开始向临时文件写入数据之前,通常都可以使用此值指定的内存量。此外,多个正在运行的会话也可能并发执行此类操作。因此,使用的总内存量可能是work_mem值的数倍;选择此值时必须考虑这一点。排序操作用于ORDER BY、DISTINCT和归并连接。Hash 表用于哈希连接、基于 hash 的聚合、Memoize 节点以及基于 hash 的IN子查询处理。与等效的排序操作相比,基于 hash 的操作通常对可用内存更敏感。Hash 表的内存上限由
work_mem乘以hash_mem_multiplier计算得到。因此,基于 hash 的操作可以使用超过通常的work_mem基础量的内存。hash_mem_multiplier(floating point) #用于计算基于 hash 的操作可以使用的最大内存量。最终上限由
work_mem乘以hash_mem_multiplier确定。默认值为 2.0,使基于 hash 的操作可以使用通常的work_mem基础量的两倍。如果查询操作经常溢写磁盘,可以考虑增加
hash_mem_multiplier,尤其是在单纯增加work_mem会导致内存压力的情况下(内存压力通常表现为间歇性的内存不足错误)。对于混合工作负载,默认值 2.0 通常有效。如果work_mem已增加到 40MB 或更高,则将该值进一步设为 2.0 - 8.0 或更高可能有效。maintenance_work_mem(integer) #指定维护操作(如
VACUUM、CREATE INDEX和ALTER TABLE ADD FOREIGN KEY)可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 64 兆字节(64MB)。由于一个数据库会话一次只能执行一个此类操作,而一个数据库系统通常也不会并发运行很多此类操作,因此可以安全地将该值设得远大于work_mem。更大的设置可能改善清理和恢复数据库转储的性能。注意,自动清理运行时,最多可能分配此内存量的 autovacuum_max_workers 倍,因此不要将默认值设得过高。单独设置 autovacuum_work_mem 可能有助于控制这一点。
注意,在收集死元组标识符时,
VACUUM最多只能使用1GB内存。autovacuum_work_mem(integer) #指定每个自动清理工作进程可使用的最大内存量。如果未指定单位,则以千字节为单位。默认值为 -1,表示改用 maintenance_work_mem 的值。该设置不影响其他上下文中运行的
VACUUM的行为。此参数只能在postgresql.conf文件中或服务器命令行上设置。在收集死元组标识符时,自动清理最多只能使用
1GB内存,因此将autovacuum_work_mem设得更高,不会影响自动清理扫描表时能收集的死元组数量。vacuum_buffer_usage_limit(integer) #指定
VACUUM和ANALYZE命令使用的缓冲区访问策略的大小。设为0时,允许操作使用任意数量的shared_buffers缓冲区。否则,有效大小范围为128 kB至16 GB。如果指定的大小超过shared_buffers大小的 1/8,则会在不提示的情况下限制为该值。默认值为256 kB。如果未指定单位,则以千字节为单位。此参数可以随时设置。在执行 VACUUM 和 ANALYZE 时,可以通过BUFFER_USAGE_LIMIT选项覆盖此设置。较大的设置可能使VACUUM和ANALYZE运行得更快,但设置过大可能会将过多其他有用页面逐出共享缓冲区。logical_decoding_work_mem(integer) #指定逻辑解码在将部分已解码的更改写入本地磁盘之前可使用的最大内存量。它限制了流式逻辑复制连接使用的内存量。默认值为 64 兆字节(
64MB)。由于每个复制连接仅使用一个此大小的缓冲区,而一个数据库系统通常不会同时有很多此类连接(受max_wal_senders限制),因此可以安全地将该值设得远高于work_mem,以减少写入磁盘的已解码更改数量。max_stack_depth(integer) #指定服务器执行栈的最大安全深度。此参数的理想设置是由内核强制执行的实际栈大小限制(如由
ulimit -s或本地等效设置),减去大约一兆字节的安全余量。需要安全余量是因为服务器中并非每个例程都检查栈深度,而只在关键的潜在递归例程中检查。如果未指定单位,则将其视为千字节。默认设置为两兆字节(2MB),这是保守且不太可能引起崩溃的小值。但是,这可能太小,无法执行复杂函数。只有超级用户和具有适当SET权限的用户才能更改此设置。把
max_stack_depth参数设置得高于实际的内核限制将意味着一个失控的递归函数可能会导致一个独立的后端进程崩溃。在 PostgreSQL 能够检测内核限制的平台上,服务器将不允许把这个参数设置为一个不安全的值。不过,并非所有平台都能提供该信息,所以我们还是建议你在选择值时要小心。shared_memory_type(enum) #指定服务器用于主共享内存区域的共享内存实现,该区域存放 PostgreSQL 的共享缓冲区及其他共享数据。可选值为
mmap(使用mmap分配的匿名共享内存)、sysv(通过shmget分配的 System V 共享内存)和windows(Windows 共享内存)。并非所有平台都支持所有值;第一个受支持的选项是该平台的默认值。sysv不是任何平台的默认选项,通常不建议使用,因为它一般需要更改内核的默认设置才能分配大量内存(见第 19.4.1 节)。此参数只能在服务器启动时设置。dynamic_shared_memory_type(enum) #指定服务器应使用的动态共享内存实现。可选值为
posix(使用shm_open分配的 POSIX 共享内存)、sysv(通过shmget分配的 System V 共享内存)、windows(Windows 共享内存)、mmap(使用存放在数据目录中的内存映射文件模拟共享内存)。并非所有平台都支持所有值;第一个受支持的选项通常是该平台的默认值。mmap不是任何平台的默认选项,通常不建议使用,因为操作系统可能会反复将修改过的页面写回磁盘,增加系统 I/O 负载;不过,在调试、将pg_dynshmem目录存放在 RAM 磁盘上,或其他共享内存设施不可用时,它可能有用。此参数只能在服务器启动时设置。min_dynamic_shared_memory(integer) #指定服务器启动时为并行查询分配的内存量。当此内存区域不足或被并发查询耗尽时,新的并行查询会尝试使用
dynamic_shared_memory_type配置的方法,临时向操作系统分配额外的共享内存;由于内存管理开销,这可能较慢。在支持huge_pages设置的操作系统上,启动时通过min_dynamic_shared_memory分配的内存会受到该设置的影响;在自动管理巨型页的操作系统上,这些内存也可能更容易受益于较大的页。默认值为0(不分配)。此参数只能在服务器启动时设置。
20.4.2. 磁盘 #
temp_file_limit(integer) #指定一个进程可用于临时文件的最大磁盘空间,例如排序和 hash 临时文件,或保留游标的存储文件。尝试超过此限制的事务将被取消。如果未指定单位,则以千字节为单位。
-1(默认值)表示没有限制。只有超级用户和具有适当SET权限的用户才能更改此设置。此设置限制单个 PostgreSQL 进程在任意时刻使用的所有临时文件的总空间。需要注意,显式临时表所用的磁盘空间不计入该上限;计入的是查询执行过程中内部使用的临时文件。
file_extend_method(enum) #指定在诸如
COPY这类批量操作期间扩展数据文件时所使用的方法。默认会根据操作系统选择第一个可用选项:posix_fallocate(Unix)使用标准 POSIX 接口分配磁盘空间,但某些系统缺少该接口。如果接口存在但底层文件系统不支持,本选项会静默回退到write_zeros。已知当前版本的 BTRFS 在使用该选项时会禁用压缩。在提供该函数的系统上,这是默认值。write_zeros通过写入全零数据块来扩展文件。在不提供posix_fallocate函数的系统上,这是默认值。
当数据文件扩展的块数不超过 8 个时,总是使用
write_zeros方法。
20.4.3. 内核资源使用 #
max_files_per_process(integer) #设置每个服务器子进程允许同时打开的最大文件数量。默认值为一千个文件。如果内核强制实施了安全的每进程上限,就不必担心此设置。但在某些平台上(尤其是大多数 BSD 系统),内核允许单个进程打开的文件数量很大,如果很多进程都尝试打开这么多文件,就会远超系统实际能够支持的总量。如果遇到“Too many open files”(打开的文件过多)错误,可尝试减小此设置。此参数只能在服务器启动时设置。
20.4.4. 基于代价的清理延迟 #
执行 VACUUM 和 ANALYZE 命令期间,系统维护一个内部计数器,记录已执行的各种 I/O 操作的估算代价。当累计代价达到上限(由 vacuum_cost_limit 指定)时,执行该操作的进程会休眠一小段时间,时长由 vacuum_cost_delay 指定。随后重置计数器并继续执行。
此功能让管理员能够降低这些命令对并发数据库活动的 I/O 影响。在许多情况下,VACUUM 和 ANALYZE 等维护命令是否快速完成并不重要,但避免它们显著干扰系统执行其他数据库操作的能力通常很重要。基于代价的清理延迟为管理员提供了实现这一点的方法。
对于手动执行的 VACUUM 命令,此功能默认禁用。要启用它,将 vacuum_cost_delay 变量设为非零值。
vacuum_cost_delay(floating point) #超过代价上限后,进程将休眠的时长。如果未指定单位,则以毫秒为单位。默认值为 0,表示禁用基于代价的清理延迟功能。正值会启用基于代价的清理。
使用基于代价的清理时,
vacuum_cost_delay的合适值通常很小,可能不到 1 毫秒。虽然vacuum_cost_delay可以设为以毫秒为单位的小数值,但较旧的平台可能无法准确计量这种延迟。在这些平台上,若要让VACUUM的资源用量超过延迟设为 1ms 时的水平,需要调整其他清理代价参数。尽管如此,仍应将vacuum_cost_delay设为平台能够稳定计量的尽可能小的值;较大的延迟没有帮助。vacuum_cost_page_hit(integer) #清理在共享缓冲区缓存中找到的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享 hash 表和扫描页内容的代价。默认值为 1。
vacuum_cost_page_miss(integer) #清理必须从磁盘读取的缓冲区时所计入的估算代价。它表示锁定缓冲池、查找共享 hash 表、从磁盘读取所需数据块并扫描其内容所需的工作量。默认值为 2。
vacuum_cost_page_dirty(integer) #清理操作修改原本干净的数据块时所计入的估算代价。它表示再次将脏块刷盘所需的额外 I/O。默认值为 20。
vacuum_cost_limit(integer) #会使清理进程休眠的累计代价。默认值为 200。
注意
某些操作持有关键的锁,因此应尽快完成。这些操作期间不会发生基于代价的清理延迟,所以累计代价可能远超指定上限。为避免此时出现无益的长时间延迟,实际延迟按 vacuum_cost_delay * accumulated_balance / vacuum_cost_limit 计算,但最大不超过 vacuum_cost_delay * 4。
20.4.5. 后台写入器 #
有一个独立的服务器进程,称为后台写入器,负责写出“脏”(新的或修改过的)共享缓冲区。当干净的共享缓冲区数量似乎不足时,后台写入器会将一些脏缓冲区写入文件系统,并将其标记为干净。这可以降低处理用户查询的服务器进程找不到干净缓冲区、因而不得不自行写出脏缓冲区的可能性。不过,后台写入器确实会使总体 I/O 负载有所增加:反复变脏的页面原本可能在每个检查点间隔中只写出一次,而后台写入器可能在同一间隔内随着它变脏而多次写出。本节参数可用于根据实际需求调整此行为。
bgwriter_delay(integer) #指定后台写入器各轮活动之间的延迟。每一轮中,写入器会对一定数量的脏缓冲区发出写操作(由下面的参数控制),然后休眠
bgwriter_delay指定的时长,再重复此过程。不过,当缓冲池中没有脏缓冲区时,它会进入更长的休眠,而不受bgwriter_delay限制。如果未指定单位,则以毫秒为单位。默认值为 200 毫秒(200ms)。注意,在许多系统上,休眠延迟的有效分辨率为 10 毫秒;将bgwriter_delay设为不是 10 的倍数的值,可能与将它设为下一个更大的 10 的倍数效果相同。此参数只能在postgresql.conf文件中或服务器命令行上设置。bgwriter_lru_maxpages(integer) #后台写入器每轮写出的缓冲区数量不会超过此值。设为零会禁用后台写入。(由另一个独立的专用辅助进程管理的检查点不受影响。)默认值为 100 个缓冲区。此参数只能在
postgresql.conf文件中或服务器命令行上设置。bgwriter_lru_multiplier(floating point) #每轮写出的脏缓冲区数量取决于最近几轮服务器进程所需的新缓冲区数量。将近期平均需求乘以
bgwriter_lru_multiplier,即可估算下一轮所需的缓冲区数量。写入器会写出脏缓冲区,直到可用的干净且可重用缓冲区达到这一数量。(不过,每轮写出的缓冲区数量不会超过bgwriter_lru_maxpages。)因此,设为 1.0 表示采用“恰好及时”策略,写出的缓冲区数量恰好等于预测需求量。更大的值可为需求突增留出余量,而更小的值则有意将部分写操作留给服务器进程执行。默认值为 2.0。此参数只能在postgresql.conf文件中或服务器命令行上设置。bgwriter_flush_after(integer) #每当后台写入器写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用
fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 shared_buffers 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即BLCKSZ字节,通常为 8kB。有效范围为0(禁用强制写回)至2MB。Linux 上的默认值为512kB,其他平台为0。(如果BLCKSZ不是 8kB,默认值和最大值将按比例变化。)此参数只能在postgresql.conf文件中或服务器命令行上设置。
较小的 bgwriter_lru_maxpages 和 bgwriter_lru_multiplier 可以降低后台写入器造成的额外 I/O 负载,但也会增加服务器进程必须自行发出写操作的可能性,从而延迟交互式查询。
20.4.6. 异步行为 #
backend_flush_after(integer) #每当单个后端写出的数据超过此数量时,就尝试强制操作系统将这些写操作发往底层存储。这样可以限制内核页缓存中的脏数据量,降低在检查点结束时调用
fsync,或操作系统在后台以较大批次写回数据时发生停顿的可能性。通常,这能大幅降低事务延迟,但在某些情况下性能可能下降,尤其是工作负载大于 shared_buffers 而小于操作系统页缓存时。此设置在某些平台上可能没有效果。如果未指定单位,则以块为单位,即BLCKSZ字节,通常为 8kB。有效范围为0(禁用强制写回)至2MB。默认值为0,即不强制写回。(如果BLCKSZ不是 8kB,最大值将按比例变化。)effective_io_concurrency(integer) #设置 PostgreSQL 预期可以同时执行的并发磁盘 I/O 操作数量。提高此值会增加单个 PostgreSQL 会话尝试并行发起的 I/O 操作数量。允许的范围为 1 至 1000,或设为零以禁用异步 I/O 请求。目前,此设置仅影响位图堆扫描。
对于磁盘,可以将为数据库提供存储的 RAID 0 条带或 RAID 1 镜像中的独立磁盘数量作为合理初始值。(对于 RAID 5,不应计入校验盘。)不过,如果数据库经常忙于执行并发会话发出的多个查询,较小的值可能就足以使磁盘阵列保持繁忙。超过使磁盘保持繁忙所需的值只会增加 CPU 开销。SSD 和其他基于内存的存储通常可以处理大量并发请求,因此最佳值可能达到数百。
异步 I/O 依赖于有效的
posix_fadvise函数,而某些操作系统缺少此函数。如果该函数不存在,将此参数设为任何非零值都会报错。在某些操作系统(如 Solaris)上,该函数虽然存在,却实际上不做任何事情。支持此功能的系统上默认值为 1,其他系统为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 ALTER TABLESPACE)。
maintenance_io_concurrency(integer) #与
effective_io_concurrency类似,但用于为多个客户端会话执行的维护工作。支持此功能的系统上默认值为 10,其他系统为 0。对于位于特定表空间中的表,可以通过设置同名的表空间参数覆盖此值(见 ALTER TABLESPACE)。
max_worker_processes(integer) #设置系统能够支持的后台进程的最大数量。此参数只能在服务器启动时设置。默认值为 8。
运行备库时,必须将此参数设为与主库相同或更大的值。否则,备库上将不允许执行查询。
更改此值时,也应考虑调整 max_parallel_workers、max_parallel_maintenance_workers、max_parallel_workers_per_gather。
max_parallel_workers_per_gather(integer) #设置单个
Gather或Gather Merge节点能够启动的工作进程的最大数量。并行工作进程取自 max_worker_processes 建立的进程池,并受到 max_parallel_workers 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,计划会使用少于预期的工作进程运行,效率可能较低。默认值为 2。设为 0 会禁用并行查询执行。注意,并行查询消耗的资源可能远多于非并行查询,因为每个工作进程都是完全独立的进程,对系统的影响大致相当于额外增加一个用户会话。选择此设置的值,以及配置其他控制资源使用的设置(如 work_mem)时,都应考虑这一点。
work_mem等资源限制分别应用于每个工作进程,因此所有进程的总资源用量可能远高于单个进程通常的用量。例如,使用 4 个工作进程的并行查询,其 CPU 时间、内存、I/O 带宽等用量可能达到完全不使用工作进程的查询的 5 倍。并行查询的更多信息参见第 15 章。
max_parallel_maintenance_workers(integer) #设置单个工具命令能够启动的并行工作进程的最大数量。目前,支持使用并行工作进程的工具命令包括:构建 B-树索引时的
CREATE INDEX,以及不带FULL选项的VACUUM。并行工作进程取自 max_worker_processes 建立的进程池,并受到 max_parallel_workers 的限制。注意,运行时实际可用的工作进程可能不足请求的数量。此时,工具操作会使用少于预期的工作进程运行。默认值为 2。设为 0 会禁止工具命令使用并行工作进程。注意,并行工具命令的内存消耗不应明显高于等效的非并行操作。这与并行查询的策略不同,后者的资源限制通常分别应用于每个工作进程。并行工具命令将
maintenance_work_mem视为整个工具命令的资源上限,而不论使用多少个并行工作进程。不过,并行工具命令仍可能消耗多得多的 CPU 资源和 I/O 带宽。max_parallel_workers(integer) #设置系统能够为并行操作提供的工作进程的最大数量。默认值为 8。增大或减小此值时,也应考虑调整 max_parallel_maintenance_workers、max_parallel_workers_per_gather。此外,将此值设得大于 max_worker_processes 没有效果,因为并行工作进程取自该设置建立的工作进程池。
-
parallel_leader_participation(boolean) # 允许领导者进程执行
Gather和Gather Merge节点下的查询计划,而不是等待工作进程。默认值为on。将此值设置为off,可以降低工作进程因领导者读取元组不够快而被阻塞的可能性,但在产生第一批元组之前,领导者进程必须等待工作进程启动。领导者对性能的帮助或妨碍程度取决于计划类型、工作进程数量和查询持续时间。old_snapshot_threshold(integer) #设置查询快照在使用时不发生“snapshot too old”错误的最短可用时间。已死亡超过该阈值的数据允许被清理掉。这有助于在快照长期保持使用时防止膨胀。为了避免因清理本应对该快照可见的数据而得到错误结果,当快照年龄超过该阈值,并且该快照被用于读取某个自其建立以来已被修改过的页面时,就会报错。
如果指定值时没有单位,则以分钟为单位。值为
-1(默认值)会禁用此特性,相当于把快照年龄上限设为无穷大。该参数只能在服务器启动时设置。对生产环境而言,有用的取值大概从几个小时到几天不等。较小的值(例如
0或1min)之所以被允许,只是因为它们有时可用于测试。虽然允许设置到60d这么高,但请注意,在许多工作负载中,严重膨胀或事务 ID 回卷可能会在更短时间内发生。启用此特性后,关系末尾释放出来的空间将不能返还给操作系统,因为那样可能会移除检测“snapshot too old”条件所需的信息。分配给某个关系的全部空间都会一直归属于该关系,只能在该关系内部重用,除非显式释放(例如使用
VACUUM FULL)。该设置并不尝试保证在任何特定情况下都一定会产生错误。实际上,如果仍能从某个对象(例如已经物化结果集的游标)生成正确结果,那么即使被引用表中的底层行已经被清理掉,也不会报错。有些表不能安全地提前清理,因此不会受此设置影响,例如系统目录。对这类表来说,此设置既不会减少膨胀,也不会在扫描时引入“snapshot too old”错误的可能性。
报告文档问题
阅读 上游文档. 通过 PostgreSQL 文档反馈表单.