Re: Adding basic NUMA awareness
Tomas Vondra <tomas@vondra.me>
From: Tomas Vondra <tomas@vondra.me>
To: Andres Freund <andres@anarazel.de>
Cc: Greg Burd <greg@burd.me>, Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>,
PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>,
Dmitry Dolgov <9erthalion6@gmail.com>
Date: 2025-07-17T21:11:16Z
Lists: pgsql-hackers
Attachments
- v2-0007-NUMA-pin-backends-to-NUMA-nodes.patch (text/x-patch) patch v2-0007
- v2-0006-NUMA-interleave-PGPROC-entries.patch (text/x-patch) patch v2-0006
- v2-0005-NUMA-clockweep-partitioning.patch (text/x-patch) patch v2-0005
- v2-0004-NUMA-partition-buffer-freelist.patch (text/x-patch) patch v2-0004
- v2-0003-freelist-Don-t-track-tail-of-a-freelist.patch (text/x-patch) patch v2-0003
- v2-0002-NUMA-localalloc.patch (text/x-patch) patch v2-0002
- v2-0001-NUMA-interleaving-buffers.patch (text/x-patch) patch v2-0001
Hi, Here's a v2 of the patch series, with a couple changes: * I simplified the various freelist partitioning by keeping only the "node" partitioning (so the cpu/pid strategies are gone). Those were meant for experimenting, but it made the code more complicated so I ditched it. * I changed the freelist partitioning scheme a little bit, based on the discussion in this thread. Instead of having a single "partition" per NUMA node, there's not a minimum number of partitions (set to 4). So even if your system is not NUMA, you'll have 4 of them. If you have 2 nodes, you'll still have 4, and each node will get 2. With 3 nodes we get 6 partitions (we need 2 per node, and we want to keep the number equal to keep things simple). Once the number of nodes exceeds 4, the heuristics switches to one partition per node. I'm aware there's a discussion about maybe simply removing freelists entirely. If that happens, this becomes mostly irrelevant, of course. The code should also make sure the freelists "agree" with how the earlier patch mapped the buffers to NUMA nodes, i.e. the freelist should only contain buffers from the "correct" NUMA node, etc. I haven't paid much attention to this - I believe it should work for "nice" values of shared buffers (when it evenly divides between nodes). But I'm sure it's possible to confuse that (won't cause crashes, but inefficiency). * There's now a patch partitioning clocksweep, using the same scheme as the freelists. I came to the conclusion it doesn't make much sense to partition these things differently - I can't think of a reason why that would be advantageous, and it makes it easier to reason about. The clocksweep partitioning is somewhat harder, because it affects BgBufferSync() and related code. With the partitioning we now have multiple "clock hands" for different ranges of buffers, and the clock sweep needs to consider that. I modified BgBufferSync to simply loop through the ClockSweep partitions, and do a small cleanup for each. It does work, as in "it doesn't crash". But this part definitely needs review to make sure I got the changes to the "pacing" right. * This new freelist/clocksweep partitioning scheme is however harder to disable. I now realize the GUC may quite do the trick, and there even is not a GUC for the clocksweep. I need to think about this, but I'm not even how feasible it'd be to have two separate GUCs (because of how these two pieces are intertwined). For now if you want to test without the partitioning, you need to skip the patch. I did some quick perf testing on my old xeon machine (2 NUMA nodes), and the results are encouraging. For a read-only pgbench (2x shared buffers, within RAM), I saw an increase from 1.1M tps to 1.3M. Not crazy, but not bad considering the patch is more about consistency than raw throughput. For a read-write pgbench I however saw some strange drops/increases of throughput. I suspect this might be due to some thinko in the clocksweep partitioning, but I'll need to take a closer look. regards -- Tomas Vondra
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Sort guc_parameters.dat alphabetically by name
- fce7c73fba4e 19 (unreleased) cited