PostgreSQL 18 preview - 引入 NUMA 感知能力
PostgreSQL 18 preview - 引入 NUMA 感知能力
NUMA (Non-Uniform Memory Access) 是一种多处理器系统的内存架构。在这种架构下,处理器访问本地内存(离它近的内存)比访问远程内存(离其他处理器近的内存)速度更快。对于像 PostgreSQL 这样需要管理大量内存(尤其是共享缓冲区)的数据库系统来说,了解数据实际存储在哪个 NUMA 节点上,对于性能诊断和潜在的优化非常重要。
PostgreSQL 这几个补丁共同实现了让 PostgreSQL 能够感知并报告其使用的内存所在的 NUMA 节点信息,特别是针对共享缓冲区。
未来可能会增加更多的能力, 例如亲和配置, 根据用户/数据库/进程/SQL层面来分配或绑定CPU核, 就近使用内存等.
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=65c298f61fc70f2f960437c05649f71b862e2c48
Add support for basic NUMA awareness
author Tomas Vondra <[email protected]>
Mon, 7 Apr 2025 20:51:49 +0000 (22:51 +0200)
committer Tomas Vondra <[email protected]>
Mon, 7 Apr 2025 21:08:17 +0000 (23:08 +0200)
commit 65c298f61fc70f2f960437c05649f71b862e2c48
tree c6f990de6bee1ab4c8b01f18c9e9b8f44e9dcc7c tree
parent 17bcf4f5450430f67b744c225566c9e0e6413e95 commit | diff
Add support for basic NUMA awareness Add basic NUMA awareness routines, using a minimal src/port/pg_numa.c
portability wrapper and an optional build dependency, enabled by
--with-libnuma configure option. For now this is Linux-only, other
platforms may be supported later.
A built-in SQL function pg_numa_available() allows checking NUMA
support, i.e. that the server was built/linked with the NUMA library.
The main function introduced is pg_numa_query_pages(), which allows
determining the NUMA node for individual memory pages. Internally the
function uses move_pages(2) syscall, as it allows batching, and is more
efficient than get_mempolicy(2).
Author: Jakub Wartak <[email protected]>
Co-authored-by: Bertrand Drouvot <[email protected]>
Reviewed-by: Andres Freund <[email protected]>
Reviewed-by: Álvaro Herrera <[email protected]>
Reviewed-by: Tomas Vondra <[email protected]>
Discussion: https://postgr.es/m/CAKZiRmxh6KWo0aqRqvmcoaX2jUxZYb4kGp3N%3Dq1w%2BDiH-696Xw%40mail.gmail.com
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=ba2a3c2302f1248496322eba917b17a421499388
Add pg_buffercache_numa view with NUMA node info
author Tomas Vondra <[email protected]>
Mon, 7 Apr 2025 20:56:57 +0000 (22:56 +0200)
committer Tomas Vondra <[email protected]>
Mon, 7 Apr 2025 21:08:17 +0000 (23:08 +0200)
commit ba2a3c2302f1248496322eba917b17a421499388
tree 54101e42df554d6c4f04c0bb79263fb3b55efde7 tree
parent 8cc139bec34a2971b0682a04eb52ce7b3f5bb425 commit | diff
Add pg_buffercache_numa view with NUMA node info Introduces a new view pg_buffercache_numa, showing NUMA memory nodes
for individual buffers. For each buffer the view returns an entry for
each memory page, with the associated NUMA node.
The database blocks and OS memory pages may have different size - the
default block size is 8KB, while the memory page is 4K (on x86). But
other combinations are possible, depending on configure parameters,
platform, etc. This means buffers may overlap with multiple memory
pages, each associated with a different NUMA node.
To determine the NUMA node for a buffer, we first need to touch the
memory pages using pg_numa_touch_mem_if_required, otherwise we might get
status -2 (ENOENT = The page is not present), indicating the page is
either unmapped or unallocated.
The view may be relatively expensive, especially when accessed for the
first time in a backend, as it touches all memory pages to get reliable
information about the NUMA node. This may also force allocation of the
shared memory.
Author: Jakub Wartak <[email protected]>
Reviewed-by: Andres Freund <[email protected]>
Reviewed-by: Bertrand Drouvot <[email protected]>
Reviewed-by: Tomas Vondra <[email protected]>
Discussion: https://postgr.es/m/CAKZiRmxh6KWo0aqRqvmcoaX2jUxZYb4kGp3N%3Dq1w%2BDiH-696Xw%40mail.gmail.com
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=8cc139bec34a2971b0682a04eb52ce7b3f5bb425
Introduce pg_shmem_allocations_numa view
author Tomas Vondra <[email protected]>
Mon, 7 Apr 2025 20:54:49 +0000 (22:54 +0200)
committer Tomas Vondra <[email protected]>
Mon, 7 Apr 2025 21:08:17 +0000 (23:08 +0200)
commit 8cc139bec34a2971b0682a04eb52ce7b3f5bb425
tree 67e2f302199d1ac5fe406961ccd5fe47f469bdf9 tree
parent 65c298f61fc70f2f960437c05649f71b862e2c48 commit | diff
Introduce pg_shmem_allocations_numa viewIntroduce new pg_shmem_alloctions_numa view with information about how
shared memory is distributed across NUMA nodes. For each shared memory
segment, the view returns one row for each NUMA node backing it, with
the total amount of memory allocated from that node.
The view may be relatively expensive, especially when executed for the
first time in a backend, as it has to touch all memory pages to get
reliable information about the NUMA node. This may also force allocation
of the shared memory.
Unlike pg_shmem_allocations, the view does not show anonymous shared
memory allocations. It also does not show memory allocated using the
dynamic shared memory infrastructure.
Author: Jakub Wartak <[email protected]>
Reviewed-by: Andres Freund <[email protected]>
Reviewed-by: Bertrand Drouvot <[email protected]>
Reviewed-by: Tomas Vondra <[email protected]>
Discussion: https://postgr.es/m/CAKZiRmxh6KWo0aqRqvmcoaX2jUxZYb4kGp3N%3Dq1w%2BDiH-696Xw%40mail.gmail.com
AI 解读
好的,我们来解读一下这两个相关的 PostgreSQL 补丁:
核心主题:为 PostgreSQL 增加 NUMA 感知能力
NUMA (Non-Uniform Memory Access) 是一种多处理器系统的内存架构。在这种架构下,处理器访问本地内存(离它近的内存)比访问远程内存(离其他处理器近的内存)速度更快。对于像 PostgreSQL 这样需要管理大量内存(尤其是共享缓冲区)的数据库系统来说,了解数据实际存储在哪个 NUMA 节点上,对于性能诊断和潜在的优化非常重要。
这两个补丁共同实现了让 PostgreSQL 能够感知并报告其使用的内存所在的 NUMA 节点信息,特别是针对共享缓冲区。
补丁 1:Add support for basic NUMA awareness (添加对基本 NUMA 感知的支持)
目的: 这个补丁为 PostgreSQL 引入了与操作系统 NUMA 功能交互的基础设施和底层函数。它是后续 NUMA 相关功能的基础。 主要内容:
引入 src/port/pg_numa.c: 这是一个新的、最小化的可移植性封装层。它将特定于平台的 NUMA 操作(目前仅限 Linux)封装起来,以便未来可能支持其他操作系统。添加 --with-libnuma配置选项: NUMA 支持变成了一个可选的编译时依赖。只有在编译 PostgreSQL 时使用了这个选项,并且系统安装了libnuma开发库,相关的 NUMA 功能才会被启用。这避免了在不需要或不支持 NUMA 的系统上强制引入依赖。平台限制: 目前这个功能仅支持 Linux。 引入 SQL 函数 pg_numa_available(): 允许用户在运行时检查当前的 PostgreSQL 服务器实例是否编译并链接了 NUMA 库,即是否启用了 NUMA 支持。引入核心函数 pg_numa_query_pages(): 这是此补丁添加的最主要的功能性函数。它允许查询单个内存页所属的 NUMA 节点。内部实现: 该函数内部使用了 Linux 的 move_pages(2)系统调用来查询页面信息。选择move_pages(即使只是查询而不移动) 是因为它支持批量查询多个页面,通常比另一个选项get_mempolicy(2)更高效。
补丁 2:Add pg_buffercache_numa view with NUMA node info (添加包含 NUMA 节点信息的 pg_buffercache_numa 视图)
目的: 这个补丁利用第一个补丁提供的基础能力,创建了一个用户可以直接查询的视图,用于查看 PostgreSQL 共享缓冲区中数据块所使用的内存页对应的 NUMA 节点。 主要内容:
引入新视图 pg_buffercache_numa: 这是用户可以直接使用的主要功能。它展示了共享缓冲区中每个缓冲块(Buffer)对应的内存页及其所在的 NUMA 节点。处理块与页的大小差异: 补丁说明特别指出,PostgreSQL 的数据块大小(默认 8KB)和操作系统的内存页大小(x86 上常为 4KB)可能不同。这意味着一个数据库缓冲块可能会跨越多个物理内存页。 视图输出粒度: 因此,对于每个缓冲块,该视图会为构成它的每一个内存页返回一条记录,并标明该页关联的 NUMA 节点。如果一个 8KB 的缓冲块使用了两个 4KB 的内存页,那么这个缓冲块在该视图中就会有两条记录。 需要 "触摸" 内存页 ( pg_numa_touch_mem_if_required): 在查询 NUMA 节点之前,需要确保对应的内存页已经被操作系统实际分配并映射了物理内存。如果页尚未被访问("touch"),底层系统调用(如move_pages)可能会返回-2 (ENOENT),表示页面不存在或未分配。因此,查询前会调用pg_numa_touch_mem_if_required来“唤醒”这些页面。性能考量: 这个视图的查询可能代价较高,尤其是在一个后端进程中首次访问时。因为它需要“触摸”所有涉及的共享内存页,这可能会强制操作系统分配物理内存(如果之前尚未分配),并逐页查询 NUMA 信息。这不仅耗时,也可能增加内存使用压力。
pg_buffercache_numa 视图来了解:共享缓冲区中的数据页是否均匀分布在所有 NUMA 节点上? 某个后端进程访问的数据页是否主要位于其运行的 CPU 所在的 NUMA 节点上? 是否存在 NUMA 内存访问不平衡导致的潜在性能瓶颈?
这对于在大型 NUMA 服务器上进行性能分析和调优非常有价值。
总结:
这两个补丁协同工作,为 PostgreSQL 带来了初步的 NUMA 感知能力:
第一个补丁建立了与操作系统 NUMA 功能交互的基础框架和核心查询函数( pg_numa_query_pages),是底层的技术支持。第二个补丁利用这个基础框架,创建了一个面向用户的视图( pg_buffercache_numa),使得用户可以具体地观察到共享缓冲区内数据页在 NUMA 节点上的分布情况。
目前这主要是观察和诊断性质的功能,尚未包含基于 NUMA 感知的自动内存管理或调度优化。但它为理解 PostgreSQL 在 NUMA 环境下的内存行为提供了重要的可见性,并为未来可能的 NUMA 优化工作铺平了道路。用户在使用 pg_buffercache_numa 视图时需要注意其潜在的性能开销。
我们来解读一下这个关于 pg_shmem_allocations_numa 视图的补丁:
补丁核心内容:引入 pg_shmem_allocations_numa 视图
目的: 这个补丁为 PostgreSQL 增加了一个名为 pg_shmem_allocations_numa的新系统视图。其主要目的是让用户能够了解 PostgreSQL 的主共享内存段是如何在不同的 NUMA 节点之间分布的。视图提供的信息: 一行显示节点 A 为该段贡献的总内存量。 另一行显示节点 B 为该段贡献的总内存量。 它关注的是 PostgreSQL 启动时分配的主要共享内存区域(例如,用于共享缓冲区、锁管理器等的内存)。 对于服务器使用的每一个主共享内存段 (shared memory segment),该视图会分析其内存页实际驻留在哪些 NUMA 节点上。 输出格式: 对于某个共享内存段,如果它的内存在 NUMA 节点 A 和 NUMA 节点 B 上都有分配,那么该视图会为这个内存段生成两行记录: 简单来说,它按共享内存段和NUMA 节点进行分组,并报告每个节点上该段占用的内存大小。 性能考量: 与之前的 pg_buffercache_numa视图类似,查询pg_shmem_allocations_numa可能代价较高。尤其是在一个后端进程中首次执行该查询时,因为它需要“触摸” (touch) 共享内存段中的所有内存页,以确保能从操作系统获取到准确的 NUMA 节点信息。 这个“触摸”操作可能会触发操作系统实际分配物理内存(如果之前只是预留地址空间而未分配物理页),从而可能增加服务器的内存压力或查询的延迟。 范围和限制: 与 pg_shmem_allocations的区别: 这个新视图是对现有pg_shmem_allocations视图(显示共享内存分配的名称、大小等)的补充,但关注点不同(NUMA 分布)。不包含匿名共享内存: 它不显示那些没有明确名称的、匿名的共享内存分配。 不包含动态共享内存: 它也不显示通过 PostgreSQL 的动态共享内存 (dynamic shared memory - DSM) 机制分配的内存(例如,并行查询可能使用的内存)。它主要关注 PostgreSQL 实例启动时创建的那些静态的、主要的共享内存段。 依赖关系: 这个视图的功能依赖于之前补丁(如你之前提到的 Add support for basic NUMA awareness)所引入的底层 NUMA 查询能力(比如pg_numa_query_pages)。意义: 提供了一个宏观视角来观察 PostgreSQL 核心共享内存结构在 NUMA 架构上的物理布局。 pg_buffercache_numa关注的是数据块(Buffer)级别的 NUMA 分布,而pg_shmem_allocations_numa关注的是整个共享内存段级别的分布。这对于 DBA 在 NUMA 系统上进行性能诊断、理解内存本地性、判断是否存在内存分布倾斜等问题非常有帮助。例如,可以检查共享缓冲区的主要部分是否都落在了某一个 NUMA 节点上,而其他节点利用率很低。
总结:
这个补丁引入了一个新的诊断工具 pg_shmem_allocations_numa 视图,允许用户检查 PostgreSQL 的主要共享内存段在各个 NUMA 节点上的分布情况和大小。它提供了比 pg_buffercache_numa 更宏观的视角,但同样需要注意查询时可能带来的性能开销,并且它不覆盖匿名或动态分配的共享内存。这是 PostgreSQL NUMA 感知能力增强的又一步。