Postgresql 中文操作指南

20.4. Resource Consumption #

20.4.1. Memory #

  • shared_buffers (integer) #

    • 设置数据库服务器用于共享内存缓冲区的内存量。默认值通常为 128 兆字节 (128MB),但如果内核设置不支持(正如在 initdb 期间确定的),则可能更少。此设置必须至少为 128 千字节。但是,为了获得良好的性能,通常需要明显高于最小值的设置。如果未指定此值单位,则将其视为块,即 BLCKSZ 字节,通常为 8kB。(BLCKSZ 的非默认值更改了最小值。)此参数只能在服务器启动时设置。

    • 如果你有一个具有 1GB 或更多 RAM 的专用数据库服务器,则 shared_buffers 的合理起始值为系统中内存的 25%。有一些工作负载,即使是 shared_buffers 的更大设置也是有效的,但是因为 PostgreSQL 还依赖于操作系统缓存,所以向 shared_buffers 分配超过 40% 的 RAM 不太可能比更少的量工作得更好。shared_buffers 的较大设置通常需要相应增加 max_wal_size,以便将大量新数据或已更改数据写入的过程在较长时间内展开。

    • 在 RAM 少于 1GB 的系统上,适当的 RAM 百分比较小,以便为操作系统留下足够的可用空间。

  • huge_pages (enum) #

    • 控制是否为主共享内存区域请求巨型页面。有效值为 try(默认值)、onoff。将 huge_pages 设置为 try 时,服务器将尝试请求巨型页面,但如果失败则会回退到默认值。使用 on 时,请求巨型页面失败将阻止服务器启动。使用 off 时,将不会请求巨型页面。

    • 目前,此设置仅在 Linux 和 Windows 上受支持。当设置为 try 时,会在其他系统上忽略此设置。在 Linux 上,只有当 shared_memory_type 设置为 mmap(默认值)时,才受支持。

    • 使用巨页导致更小的页表和更少的 CPU 时间用于内存管理,从而提高性能。有关在 Linux 上使用巨页的更多详细信息,请参见 Section 19.4.5

    • 巨型页面在 Windows 上称为大页面。要使用它们,你需要将用户权限“在内存中锁定页面”分配给运行 PostgreSQL 的 Windows 用户帐户。你可以使用 Windows 组策略工具 (gpedit.msc) 来分配用户权限“在内存中锁定页面”。要以独立进程的形式(而不是作为 Windows 服务)在命令提示符上启动数据库服务器,命令提示符必须以管理员身份运行,或者必须禁用用户访问控制 (UAC)。当启用 UAC 时,正常的命令提示符在启动后会撤销用户权限“在内存中锁定页面”。

    • 请注意,此设置仅影响主共享内存区域。Linux、FreeBSD 和 Illumos 等操作系统还可以自动使用巨型页面(也称为“超”页面或“大”页面)进行常规内存分配,而无需 PostgreSQL 的明确请求。在 Linux 上,这称为“透明巨型页面”(THP)。据悉,该功能对某些 Linux 版本上的某些用户会降低 PostgreSQL 的性能,因此目前不建议使用(与 huge_pages 的显式使用不同)。

  • huge_page_size (integer) #

    • 控制巨页的大小,当使用 huge_pages启用巨页时。默认值为零 (0)。当设置为 0,系统上的默认巨页大小将被使用。此参数只能在服务器启动时设置。

    • 一些现代 64 位服务器架构上常用提供的页面大小包括:2MB_和 _1GB(Intel 和 AMD),16MB_和 _16GB(IBM POWER),以及 64kB2MB32MB_和 _1GB(ARM)。有关用法和支持的更多信息,请参见 Section 19.4.5

    • 当前,仅在 Linux 上支持非默认设置。

  • temp_buffers (integer) #

    • 设置在每个数据库会话中用于临时缓冲区的最大内存量。这些是会话本地缓冲区,仅用于访问临时表。如果指定此值时不带单位,则它将作为块,即 BLCKSZ 字节(通常为 8 KB)。默认值为 8 MB (8MB)。(如果 BLCKSZ 不是 8 KB,则默认值会相应地按比例缩放。)此设置可以在各个会话中更改,但只能在会话中第一次使用临时表之前更改;随后尝试更改值将不会对该会话产生任何影响。

    • 会话将根据 temp_buffers 指定的限制按需分配临时缓冲区。在实际上不需要许多临时缓冲区的会话中设置一个较大的值时,成本仅为缓冲区描述符,或在 temp_buffers 中每次增量约 64 字节。但是,如果实际使用了缓冲区,那么将会消耗额外的 8192 字节(或通常为 BLCKSZ 字节)。

  • max_prepared_transactions (integer) #

    • 设置可以同时处于“已准备”状态的事务的最大数量(参见 PREPARE TRANSACTION )。将此参数设置为零(这是默认值)将禁用已准备事务功能。此参数只能在服务器启动时设置。

    • 如果您不打算使用已准备的事务,则应将此参数设置为零,以防止意外创建已准备的事务。如果您正在使用已准备的事务,您可能希望 _max_prepared_transactions_至少与 max_connections一样大,以便每个会话都可能有待处理的已准备的事务。

    • 运行备用服务器时,您必须将此参数设置为与主服务器相同或更高的值。否则,备用服务器将不允许查询。

  • work_mem (integer) #

    • 设置在将临时磁盘文件写入之前,查询操作(例如排序或哈希表)使用的最大内存量基数。如果指定此值时不带单位,则它将作为千字节。默认值为 4 MB (4MB)。请注意,一个复杂的查询可能同时执行多个排序和哈希操作,每个操作通常被允许使用此值指定的大量内存,然后才开始将数据写入临时文件。此外,几个正在运行的会话可以同时执行此类操作。因此,使用的总内存可能是 work_mem 值的许多倍;在选择值时有必要记住这一点。排序操作用于 ORDER BYDISTINCT 和合并联接。哈希表用于哈希联接、基于哈希的聚合、备忘录节点和 IN 子查询的基于哈希的处理。

    • 基于哈希的操作通常比基于排序的同等操作对内存可用性更敏感。哈希表的内存限制通过将 work_mem 乘以 hash_mem_multiplier 来计算。这使得基于哈希的操作可以使用超过通常 work_mem 的基数的内存量。

  • hash_mem_multiplier (floating point) #

    • 用于计算基于哈希的操作可以使用的最大内存量。最终限制通过将 work_mem 乘以 hash_mem_multiplier 来确定。默认值为 2.0,这使得基于哈希的操作使用通常 work_mem 基数的两倍。

    • 在查询操作的溢出经常发生的需要,特别是当仅增加 work_mem 导致内存压力(内存压力通常采用间歇性地出现内存错误的形式)时,考虑在这样的环境中增加 hash_mem_multiplier。默认设置 2.0 经常有效地处理混合工作负载。在将 work_mem 增加到 40 MB 或更多的时候,在 2.0 - 8.0 或更大的范围内,较高的设置可能有效。

  • maintenance_work_mem (integer) #

    • 指定维护操作(例如 VACUUMCREATE INDEXALTER TABLE ADD FOREIGN KEY )要使用的最大内存量。如果未指定此值的单位,则将其作为千字节来采用。其默认值为 64 兆字节( 64MB )。由于数据库会话一次只能执行其中一项操作,并且一个安装项通常不会并发地运行其中许多操作,因此可以将此值设置为明显大于 work_mem 的值。更大的设置可能会提高 vacuuming 和恢复数据库转储的性能。

    • 请注意,当自动清理运行时,最多分配 autovacuum_max_workers倍此内存,因此请小心不要将默认值设置得太高。通过单独设置 autovacuum_work_mem来控制此项可能很有用。

    • 请注意,对于已死元组标识符的收集,VACUUM 仅能够使用高达 1GB 的内存。

  • autovacuum_work_mem (integer) #

    • 指定每个自动清理工作进程使用的最大内存量。如果此值未指定单位,则以千字节表示。它默认为 -1,表示应使用 maintenance_work_mem值。此设置对在其他上下文中运行时的 _VACUUM_行为没有影响。此参数只能在 _postgresql.conf_文件中或服务器命令行上设置。

    • 对于已死元组标识符的收集,自动 vacuum 仅能够使用高达 1GB 的内存,因此将 autovacuum_work_mem 设置为高于该值不会影响自动 vacuum 在扫描表时可以收集的已死元组的数量。

  • vacuum_buffer_usage_limit (integer) #

    • 指定 @{glossary.html#GLOSSARY-BUFFER-ACCESS-STRATEGY Buffer Access Strategy VACUUMANALYZE 命令使用的 [角色 =“bare”]大小。设置 0 将允许操作使用任意数量的 shared_buffers 。否则,有效大小范围为 128 kB16 GB 。如果指定的大小超过 shared_buffers 大小的 1/8,则大小将自动限定为该值。默认值为 256 kB 。如果未指定此值的单位,则将其作为千字节来采用。此参数可随时设置。在传递 BUFFER_USAGE_LIMIT 选项时,可以为 VACUUMANALYZE 覆盖此参数。较高的设置可以让 VACUUMANALYZE 更快速地运行,但设置过高可能会导致共享缓冲区中移除过多的其他有用页。

  • logical_decoding_work_mem (integer) #

    • 指定逻辑解码要使用的最大内存量,然后再将一些已解码的更改写入本地磁盘。这会限制逻辑流复制连接使用的内存量。其默认值为 64 兆字节( 64MB )。由于每个复制连接仅使用此大小的一个缓冲区,并且一个安装项通常不会并发地拥有如此多的此类连接(受 max_wal_senders 限制),因此可以将此值设置为明显高于 work_mem 的值,从而减少写入磁盘的已解码更改的数量。

  • max_stack_depth (integer) #

    • 指定服务器执行栈的最大安全深度。此参数的理想设置是内核强制执行的实际栈大小限制(由 ulimit -s 或本地等效项设置)减去大约 1 兆字节的安全裕量。需要安全裕量,因为堆栈深度并非在服务器的每个例程中都进行检查,而仅在关键的潜在递归例程中进行检查。如果未指定此值的单位,则将其作为千字节来采用。默认设置为 2 兆字节( 2MB ),该值保守且小,不太可能导致崩溃。但是,它可能太小而无法执行复杂的函数。只有超级用户和具有适当 SET 权限的用户可以更改此设置。

    • max_stack_depth 设置为高于实际内核限制将意味着失控的递归函数可能会导致单个后端进程崩溃。在 PostgreSQL 可以确定内核限制的平台上,服务器将不允许将此变量设置为不安全的价值。但是,并非所有平台都能提供这些信息,因此建议在选择值时小心。

  • shared_memory_type (enum) #

    • 指定服务器应使用该服务器用于保存 PostgreSQL 共享缓冲区和其他共享数据的共享内存区域的共享内存实现。可能的值为: mmap (用于使用 mmap 分配的匿名共享内存)、 sysv (用于通过 shmget 分配的 System V 共享内存)和 windows (用于 Windows 共享内存)。并非所有平台都支持所有值;第一个受支持的选项是该平台的默认值。通常不建议使用 sysv 选项(它并非是任何平台上的默认选项),因为它通常需要使用非默认内核设置才能进行大分配(参见 Section 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 配置的方法暂时从操作系统分配额外的共享内存,这由于内存管理开销可能会变慢。在受支持的操作系统上,使用 min_dynamic_shared_memory 在启动时分配的内存会受 huge_pages 设置的影响,并且在自动管理页面大小的操作系统上更有可能受益于大页面。默认值是 0(无)。此参数只能在服务器启动时设置。

20.4.2. Disk #

  • temp_file_limit (integer) #

    • 指定一个进程可以用于临时文件(例如排序和哈希临时文件或保留游标的存储文件)的最大磁盘空间。尝试超过此限制的事务将被取消。如果未指定单位,此值将被视为千字节。-1(默认值)表示无限制。只有超级用户和具有适当 SET 权限的用户可以更改此设置。

    • 此设置限制某个给定的 PostgreSQL 进程使用的所有临时文件在任何时间点使用的总空间。应注意,用于显式临时表(与查询执行过程中在幕后使用的临时文件相反)的磁盘空间 not 是依据此限制计算的。

20.4.3. Kernel Resource Usage #

  • max_files_per_process (integer) #

    • 设置允许每个服务器子进程同时打开的文件的最大数量。默认是一千个文件。如果内核正在强制执行每个进程的安全限制,则无需担心此设置。但在某些平台(尤其是大多数 BSD 系统)上,如果许多进程都尝试打开许多文件,则内核将允许单个进程打开比系统实际支持更多的文件。如果你发现出现“文件打开过多”的错误,请尝试降低此设置。此参数只能在服务器启动时设置。

20.4.4. Cost-based Vacuum Delay #

在执行 VACUUMANALYZE 命令期间,系统维护一个内部计数器,该计数器跟踪执行的各种 I/O 操作的估计成本。当累积成本达到限制(由 vacuum_cost_limit 指定)时,执行操作的进程将休眠短时间,如 vacuum_cost_delay 中指定的时间。然后,它将重置计数器并继续执行。

此功能的目的是允许管理员降低这些命令对并发数据库活动造成的 I/O 影响。在很多情况下,重要的是诸如 VACUUMANALYZE 之类的维护命令可以快速完成;但是,通常非常重要的是这些命令不会严重干扰系统执行其他数据库操作的能力。基于成本的真空延迟为管理员提供了一种实现此目标的方法。

此功能默认情况下禁用,用于手动发出的 VACUUM 命令。要启用它,请将 vacuum_cost_delay 变量设置为非零值。

  • vacuum_cost_delay (floating point) #

    • 当超过成本限制时进程休眠的时间。如果未指定单位,此值将被视为毫秒。默认值为零,这会禁用基于成本的真空延迟功能。正值会启用基于成本的真空。

    • 在使用基于成本的真空时,vacuum_cost_delay 的适当值通常非常小,可能不到 1 毫秒。虽然 vacuum_cost_delay 可以设置为以毫秒为单位的零碎值,但在老式平台上可能无法准确测量此类延迟。在这些平台上,增加 VACUUM's 节流资源消耗超过您在 1ms 获得的消耗,将需要更改其他真空成本参数。不过,您应该始终保持 vacuum_cost_delay 的大小在您的平台可以一致测量的范围内;大幅延迟会无济于事。

  • vacuum_cost_page_hit (integer) #

    • 在共享缓冲区高速缓存中找到的缓冲区的真空估计成本。它表示锁定缓冲池、查找共享哈希表和扫描页面内容的成本。默认值为 1。

  • vacuum_cost_page_miss (integer) #

    • 从磁盘读取缓冲区的真空估计成本。这表示锁定缓冲池、查找共享哈希表、从磁盘读取所需的块并扫描其内容所花费的精力。默认值为 2。

  • vacuum_cost_page_dirty (integer) #

    • 在 vacuum 修改之前干净的块时收取的估计成本。它表示将脏块刷新回磁盘所需的额外 I/O。默认值为 20。

  • vacuum_cost_limit (integer) #

    • 导致真空过程休眠的累积成本。默认值为 200。

Note

某些操作保留关键锁,因此应尽快完成。基于成本的 Vacuum 延迟不会在这样的操作期间发生。因此,累积的开销可能远远高于指定的限制。为了避免在这种情况下无谓的长时间延迟,实际延迟将计算为 vacuum_cost_delay * accumulated_balance / vacuum_cost_limit,最大值为 vacuum_cost_delay * 4。

20.4.5. Background Writer #

有一个称为 background writer 的单独服务器进程,其功能是发出对“脏”的(新的或已修改的)共享缓冲区的写入。当清洁的共享缓冲区数量明显不足时,后台编写器会将一些脏缓冲区写入文件系统并将其标记为干净。这降低了服务器处理用户查询的进程无法找到清洁缓冲区且必须自己写脏缓冲区的可能性。然而,后台编写器确实会造成 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. Asynchronous Behavior #

  • 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) #

  • max_parallel_workers_per_gather (integer) #

    • 设置由一个 GatherGather Merge 节点可启动的工人的最大数量。并行工作节点是从由 max_worker_processes 建立的进程池中获取的,受 max_parallel_workers 限制。请注意,请求的工作节点数量在运行时可能实际上是不可用的。如果出现这种情况,该计划将以少于预期的工作节点运行,这可能是低效的。默认值为 2。将该值设为 0 将禁用并行查询执行。

    • 请注意,并行查询可能比非并行查询使用更多得多的资源,因为每个工作节点进程都是一个完全独立的进程,它对系统的影响与一个其他用户会话大致相同。在选择此设置的值以及在配置其他控制资源使用的设置(如 work_mem)时应考虑这一点。诸如 work_mem 的资源限制将单独应用于每个工作节点,这意味着所有进程的总利用率可能远高于它通常对任何一个进程的利用率。例如,使用 4 个工作节点的并行查询可能使用多达 5 倍的 CPU 时间、内存、I/O 带宽等资源,而根本不使用工作节点的查询。

    • 有关并行查询的更多信息,请参见 Chapter 15

  • max_parallel_maintenance_workers (integer) #

    • 设置由单个实用程序命令可启动的并行工作节点的最大数量。目前,支持使用并行工作节点的并行实用程序命令仅为 CREATE INDEX 构建 B 树索引时,以及不使用 FULL 选项的 VACUUM。并行工作节点是从由 max_worker_processes 建立的进程池中获取的,受 max_parallel_workers 限制。请注意,请求的工作节点数量在运行时可能实际上是不可用的。如果出现这种情况,该实用程序操作将以少于预期的工作节点运行。默认值为 2。将该值设为 0 将禁用实用程序命令使用并行工作节点。

    • 请注意,并行实用程序命令不应使用比等效的非并行操作更多得多的内存。此策略与并行查询的策略不同,其中资源限制通常应用于每个工作节点进程。并行实用程序命令将资源限制 maintenance_work_mem 视为一个要应用于整个实用程序命令的限制,而不管并行工作节点进程的数量。但是,并行实用程序命令仍然可能使用更多得多的 CPU 资源和 I/O 带宽。

  • max_parallel_workers (integer) #

  • parallel_leader_participation (boolean) #

    • 允许引导进程在 GatherGather Merge 节点下执行查询计划,而不是等待工作节点进程。默认值为 on。将此值设为 off 可以降低工作节点被阻塞的可能性,因为引导程序无法足够快地读取元组,但要求引导程序在第一个元组生成之前等待工作节点进程启动。引导程序可以提高或降低性能的程度取决于计划类型、工作节点数量和查询持续时间。

  • old_snapshot_threshold (integer) #

    • 设置查询快照在不使用快照时发生“快照过旧”错误的最小时间。允许对死亡时间超过此阈值的数据进行清理。这有助于防止长时间使用快照造成的内存膨胀。为了防止由于清理本来快照可以见到的数据而导致不正确的结果,在快照超过此阈值且快照用于读取自构建快照后修改的页面时会生成错误。

    • 如果指定此值而没有单位,则将其视为分钟。-1 的值(默认值)禁用此功能,实际上将快照年龄限制设置为无穷大。此参数只能在服务器启动时设置。

    • 生产工作中的有用值可能在数小时到数天之间。小的值(例如 01min)仅允许使用,因为它们有时可能对测试有用。虽然允许 60d 这样的高设置,但请注意,在许多工作负载中,极端的内存膨胀或事务 ID 环绕可能在更短的时间范围内发生。

    • 启用此功能后,无法将关联末尾的可用空间释放给操作系统,因为这可能会移除检测“快照过旧”条件所需的信息。分配给关联的所有空间都将与该关联保持关联,仅在该关联内重用,除非显式释放(例如使用 VACUUM FULL)。

    • 此设置并不试图保证在任何特定情况下都会生成错误。事实上,如果正确的结果可以从(例如)已实现结果集的游标生成,即使引用的表中的底层行已被清理,也不会生成错误。有些表无法安全地提前清除,因此不会受到此设置的影响,例如系统目录。对于此类表,此设置既不会减少内存膨胀,也不会在扫描时产生“快照过旧”错误的可能性。