19.4. 资源消耗

19.4.1. Memory

  • shared_buffers ( integer )
    • 设置数据库服务器用于共享内存缓冲区的内存量。缺省值通常为 128 兆字节(128MB),但是如果您的内核设置不支持它,则缺省值可能会更少(由 initdb 确定)。此设置必须至少为 128 KB。 (非默认值BLCKSZ会更改最小值.)但是,为了获得良好的性能,通常需要使用高于该最小值的设置。该参数只能在服务器启动时设置。

如果您具有 1GB 或更大 RAM 的专用数据库服务器,则shared_buffers的合理起始值应为系统内存的 25%。在某些工作负载中,更大的shared_buffers设置是有效的,但是由于 PostgreSQL 也依赖于 os 缓存,因此为shared_buffers分配 40%以上的 RAM 不可能比较小的工作更好。 shared_buffers的较大设置通常需要max_wal_size相应增加,以便在更长的时间内分散写入大量新数据或更改数据的过程。

在具有少于 1GB RAM 的系统上,较小百分比的 RAM 是合适的,以便为 os 留出足够的空间。

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

目前,仅 Linux 和 Windows 支持此设置。当设置为try时,该设置在其他系统上将被忽略。

使用大页面可导致页面表更小,并减少用于内存 Management 的 CPU 时间,从而提高性能。有关在 Linux 上使用大页面的更多详细信息,请参见Section 18.4.5

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

请注意,此设置仅影响主共享存储区。诸如 Linux,FreeBSD 和 Illumos 之类的 os 也可以自动使用大页面(也称为“超级”页面或“大”页面)进行常规内存分配,而无需 PostgreSQL 的明确要求。在 Linux 上,这称为“透明大页面” (THP)。已知该功能会导致某些 Linux 版本上的某些用户使用 PostgreSQL 降低性能,因此目前不鼓励使用该功能(与huge_pages的显式使用不同)。

  • temp_buffers ( integer )
    • 设置每个数据库会话使用的最大临时缓冲区数。这些是会话本地缓冲区,仅用于访问临时表。默认值为八兆字节(8MB)。可以在单个会话中更改设置,但只能在会话中首次使用临时表之前进行更改;随后尝试更改该值将对该会话无效。

会话将根据需要分配临时缓冲区,直到temp_buffers给出的限制。在实际上不需要很多临时缓冲区的会话中设置较大的值的成本只是temp_buffers中每个增量的缓冲区 Descriptors,或大约 64 个字节。但是,如果实际上使用了缓冲区,则会为此消耗额外的 8192 字节(或通常为BLCKSZ字节)。

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

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

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

  • work_mem ( integer )

    • 指定内部排序操作和哈希表在写入临时磁盘文件之前要使用的内存量。该值默认为四个兆字节(4MB)。请注意,对于复杂的查询,可能会并行运行多个排序或哈希操作。在开始将数据写入临时文件之前,每个操作将被允许使用此值指定的内存量。另外,几个正在运行的会话可能会同时进行此类操作。因此,使用的总内存可能是work_mem值的许多倍;选择值时必须牢记这一事实。排序操作用于ORDER BYDISTINCT和合并联接。哈希表用于IN子查询的哈希联接,基于哈希的聚合和基于哈希的处理。
  • maintenance_work_mem ( integer )

    • 指定维护操作(例如VACUUMCREATE INDEXALTER TABLE ADD FOREIGN KEY)使用的最大内存量。默认为 64 兆字节(64MB)。由于一次数据库会话一次只能执行这些操作中的一个,并且安装中通常不会同时运行多个操作,因此可以安全地将此值设置为明显大于work_mem。较大的设置可能会提高清理和还原数据库转储的性能。

请注意,在运行自动真空时,最多可以分配此内存的autovacuum_max_workers倍,因此请注意不要将默认值设置得太高。通过单独设置autovacuum_work_mem进行控制可能很有用。

  • autovacuum_work_mem ( integer )

    • 指定每个自动真空工作进程要使用的最大内存量。它的默认值为-1,指示应改用maintenance_work_mem的值。在其他上下文中运行时,该设置对VACUUM的行为没有影响。
  • max_stack_depth ( integer )

    • 指定服务器执行堆栈的最大安全深度。此参数的理想设置是内核强制执行的实际堆栈大小限制(由ulimit -s或本地等效项设置),减去 1 MB 左右的安全裕度。需要安全裕度,因为不会在服务器中的每个例程中检查堆栈深度,而仅在关键的潜在递归例程(例如表达式评估)中检查堆栈深度。默认设置为 2 兆字节(2MB),保守地说,它很小,不太可能发生崩溃。但是,它可能太小而无法执行复杂的功能。只有超级用户可以更改此设置。

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

  • dynamic_shared_memory_type ( enum )
    • 指定服务器应使用的动态共享内存实现。可能的值为posix(对于使用shm_open分配的 POSIX 共享内存),sysv(对于通过shmget分配的 System V 共享内存),windows(对于 Windows 共享内存),mmap(使用存储在数据目录中的内存 Map 文件模拟共享内存) )和none(以禁用此功能)。并非所有平台都支持所有值。第一个受支持的选项是该平台的默认选项。通常不建议使用mmap选项(在任何平台上都不是默认选项),因为 os 可能会反复将修改后的页面写回到磁盘上,从而增加系统 I/O 负载;但是,当pg_dynshmem目录存储在 RAM 磁盘上或其他共享内存功能不可用时,这对于调试很有用。

19.4.2. Disk

  • temp_file_limit ( integer )
    • 指定进程可用于临时文件(例如,排序和哈希临时文件)或用于保留的游标的存储文件的最大磁盘空间量。尝试超过此限制的 Transaction 将被取消。该值以千字节为单位指定,并且-1(默认值)表示没有限制。只有超级用户可以更改此设置。

此设置限制了给定 PostgreSQL 进程使用的所有临时文件在任何 Moment 使用的总空间。应该注意的是,用于显式临时表的磁盘空间(与在查询执行中用于幕后的临时文件相对)计入此限制。

19 .4.3. 内核资源使用

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

19 .4.4. 基于成本的真空延迟

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

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

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

  • vacuum_cost_delay ( integer )
    • 当超出成本限制时,进程将进入休眠状态的时间(以毫秒为单位)。默认值为零,这将禁用基于成本的真空延迟功能。正值可实现基于成本的清理。请注意,在许多系统上,睡眠延迟的有效分辨率为 10 毫秒。将vacuum_cost_delay设置为不是 10 的倍数的值可能与将其设置为下一个 10 的高倍数的结果相同。

当使用基于成本的吸尘时,vacuum_cost_delay的适当值通常很小,可能为 10 或 20 毫秒。调整真空的资源消耗最好通过更改其他真空成本参数来完成。

  • vacuum_cost_page_hit ( integer )

    • 清理共享缓冲区高速缓存中找到的缓冲区的估计成本。它表示锁定缓冲池,查找共享哈希表和扫描页面内容的成本。默认值为一。
  • vacuum_cost_page_miss ( integer )

    • 清理必须从磁盘读取的缓冲区的估计成本。这表示锁定缓冲池,查找共享哈希表,从磁盘读取所需块并扫描其内容的工作。预设值为 10.
  • vacuum_cost_page_dirty ( integer )

    • 真空修改以前干净的块时收取的估计费用。它表示将脏块再次刷新到磁盘所需的额外 I/O。预设值为 20.
  • vacuum_cost_limit ( integer )

    • 累积成本将导致清理过程进入休眠状态。默认值为 200.

Note

有一些操作具有关键锁,因此应尽快完成。在此类操作期间不会发生基于成本的真空延迟。因此,成本累积可能远远高于指定的限制。为了避免这种情况下不必要的长时间延迟,实际延迟的计算方式为vacuum_cost_delay * accumulated_balance/vacuum_cost_limit,最大vacuum_cost_delay * 4.

19 .4.5. 背景 Writer

有一个称为* background writer *的独立服务器进程,其功能是发出“脏的”(新的或修改的)共享缓冲区的写操作。它写入共享缓冲区,因此服务器处理用户查询的进程很少或不需要 await 写入发生。但是,后台写入器的确会导致 I/O 负载的整体净增加,因为虽然重复写入的页面可能每个检查点间隔只能写入一次,但是后台写入器可能会多次写入它,因为在同一间隔中它被弄脏了。本小节中讨论的参数可用于调整行为以适应本地需求。

  • bgwriter_delay ( integer )

    • 指定后台写程序在活动回合之间的延迟。在每一轮中,写程序都会为一定数量的脏缓冲区(可通过以下参数控制)发出写操作。然后睡眠bgwriter_delay毫秒,然后重复。但是,当缓冲池中没有脏缓冲区时,无论bgwriter_delay为何,它都会进入更长的睡眠时间。默认值为 200 毫秒(200ms)。请注意,在许多系统上,睡眠延迟的有效分辨率为 10 毫秒。将bgwriter_delay设置为不是 10 的倍数的值可能与将其设置为下一个更高的 10 的倍数具有相同的结果。只能在postgresql.conf文件或服务器命令行中设置此参数。
  • bgwriter_lru_maxpages ( integer )

    • 在每一轮中,后台编写器将只写这么多缓冲区。将此设置为零将禁用后台写入。 (请注意,由单独的专用辅助进程 Management 的检查点不受影响.)默认值为 100 个缓冲区。此参数只能在postgresql.conf文件或服务器命令行中设置。
  • bgwriter_lru_multiplier ( floating point )

    • 在每一轮中写入的脏缓冲区的数量取决于服务器进程在最近一轮中所需的新缓冲区的数量。将最近的平均需求乘以bgwriter_lru_multiplier即可得出下一轮将需要的缓冲区数量的估计值。写入脏缓冲区,直到有许多可用的干净可重用缓冲区为止。 (但是,每轮最多写入bgwriter_lru_maxpages个缓冲区.)因此,设置为 1.0 表示精确地写入预计需要的缓冲区数量的“及时”策略。较大的值可缓解需求高峰,而较小的值则有意让写操作由服务器进程完成。默认值为 2.0. 只能在postgresql.conf文件或服务器命令行中设置此参数。
  • bgwriter_flush_after ( integer )

    • 每当后台写入器写入了超过bgwriter_flush_after个字节时,请尝试强制 os 将这些写入发布到基础存储中。这样做将限制内核页面缓存中的脏数据量,从而减少在检查点末尾发出fsync时或 os 在后台大批写回数据时出现停顿的可能性。通常,这将大大减少事务 await 时间,但是在某些情况下,尤其是对于工作负载大于shared_buffers但小于 OS 的页面缓存的情况下,性能可能会下降。此设置在某些平台上可能无效。有效范围介于02MB之间,0禁止强制写回。在 Linux 上默认为512kB,在其他地方为0。 (如果BLCKSZ不是 8kB,则默认值和最大值将按比例缩放.)只能在postgresql.conf文件或服务器命令行中设置此参数。

较小的bgwriter_lru_maxpagesbgwriter_lru_multiplier值可减少由后台编写器引起的额外 I/O 负载,但使服务器进程更有可能不得不自行发布写操作,从而延迟了交互式查询。

19 .4.6. 异步行为

  • 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功能,某些 os 缺少该功能。如果该功能不存在,则将此参数设置为除零以外的任何值都将导致错误。在某些 os(例如 Solaris)上,该功能存在,但实际上不执行任何操作。

在受支持的系统上,默认值为 1,否则为 0.可以通过设置相同名称的 tablespace 参数来为特定表空间中的表覆盖此值。

  • max_worker_processes ( integer )
    • 设置系统可以支持的最大后台进程数。该参数只能在服务器启动时设置。预设值为 8.

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

更改此值时,还要考虑调整max_parallel_workersmax_parallel_maintenance_workersmax_parallel_workers_per_gather

  • max_parallel_workers_per_gather ( integer )
    • 设置单个GatherGather Merge节点可以启动的最大工作程序数。并行工作程序是从max_worker_processes构建的,受max_parallel_workers限制的进程池中获取的。请注意,在运行时实际上可能没有所请求的 Worker 数量。如果发生这种情况,该计划将以少于预期数量的 Worker 来运行,这可能会导致效率低下。默认值为 2.将此值设置为 0 将禁用并行查询执行。

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

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

  • max_parallel_maintenance_workers ( integer )
    • 设置单个 Util 命令可以启动的并行工作程序的最大数目。当前,唯一支持并行工作程序使用的并行 Util 命令是CREATE INDEX,并且仅在构建 B 树索引时才使用。并行工作程序是从max_worker_processes构建的,受max_parallel_workers限制的进程池中获取的。请注意,在运行时实际上可能没有所请求的 Worker 数量。如果发生这种情况,Util 操作将以少于预期数量的 Worker 运行。默认值为 2.将此值设置为 0 将禁用 Util 命令对并行工作器的使用。

请注意,并行 Util 命令不应比等效的非并行操作消耗更多的内存。此策略不同于并行查询的策略,在并行查询中,资源限制通常适用于每个工作进程。并行 Util 命令将资源限制maintenance_work_mem视为要应用于整个 Util 命令的限制,而不管并行工作进程的数量如何。但是,并行 Util 命令可能仍会消耗大量 CPU 资源和 I/O 带宽。

  • max_parallel_workers ( integer )

  • backend_flush_after ( integer )

    • 每当单个后端写入的字节数超过backend_flush_after字节时,请尝试强制 os 将这些写入操作发布到基础存储。这样做将限制内核页面缓存中的脏数据量,从而减少在检查点末尾发出fsync时或 os 在后台大批写回数据时出现停顿的可能性。通常,这将大大减少事务 await 时间,但是在某些情况下,尤其是对于工作负载大于shared_buffers但小于 OS 的页面缓存的情况下,性能可能会下降。此设置在某些平台上可能无效。有效范围介于02MB之间,0禁止强制写回。默认值为0,即不强制回写。 (如果BLCKSZ不是 8kB,则最大值按比例缩放.)
  • old_snapshot_threshold ( integer )

    • 设置使用快照的最短时间,而使用快照时不会出现snapshot too old错误。该参数只能在服务器启动时设置。

超过阈值,旧数据可能会被清除。这有助于防止面对长时间使用的快照时出现膨胀。为了防止由于清理快照而导致的数据清理而导致错误结果,当快照早于此阈值并且快照用于读取自快照创建以来已被修改的页面时,将生成错误。

-1禁用此功能,这是默认值。生产工作的有用值可能从几个小时到几天不等。该设置将被强制为分钟的粒度,并且仅允许使用较小的数字(例如01min),因为它们有时可能对测试有用。虽然允许设置为最高60d,但是请注意,在许多工作负载中,可能会在更短的时间内发生极端的膨胀或事务 ID 环绕。

启用此功能后,关系末尾的释放空间无法释放给 os,因为这可能会删除检测snapshot too old条件所需的信息。分配给一个关系的所有空间都保持与该关系的关联,除非明确释放(例如,使用VACUUM FULL),否则仅在该关系内可以重用。

此设置并不试图保证在任何特定情况下都会产生错误。实际上,如果可以从(例如)实现了结果集的游标生成正确的结果,则即使引用表中的基础行已被清除,也不会产生错误。某些表无法安全地尽早清理,因此不受此设置的影响,例如系统目录。对于此类表,此设置既不会减少膨胀,也不会在扫描时产生snapshot too old错误。