| From: | Matthias van de Meent <boekewurm+postgres(at)gmail(dot)com> |
|---|---|
| To: | David Geier <geidav(dot)pg(at)gmail(dot)com> |
| Cc: | Pg Hackers <pgsql-hackers(at)postgresql(dot)org> |
| Subject: | Re: Reducing relcache memory usage 2: shrink sizeof(RelationData) |
| Date: | 2026-09-14 12:36:20 |
| Message-ID: | CAEze2Wj3rq6V+kAoXS80oTPi4s1GpsH4Gx7h-jqBBLzA64CyPQ@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On Thu, 10 Sept 2026 at 11:43, David Geier <geidav(dot)pg(at)gmail(dot)com> wrote:
>
> To further reduce relcache memory usage we can additionally shrink the
> size consumed by struct RelationData:
[...]
> All RelationData objects are allocated in CacheMemoryContext. The size
> of CacheMemoryContext can be inspected via pg_backend_memory_contexts:
>
> branch | used_bytes
> --------|---------------------------------
> master | 617,984,696 bytes = ~589.36 MiB
> patched | 562,507,232 bytes = ~536.45 MiB
>
> We save ~53 MiB or ~10% of CacheMemoryContext per backend!
That's quite nice!
> The attached patch set passes tests and consists of the following
> individual patches:
[0001-0003]
I Haven't looked at these in detail. Yes, they provide the largest
savings, but that also makes them most complicated to review in
detail. I'll stave that off for now.
> - 0004: Removes the rd_lockinfo member. RelationGetLockRelId() now
> computes it when needed. This also removes RelationInitLockInfo() and
> the initialization work associated with it.
> => sizeof(RelationData) == 304 bytes
Can we really rely on rd_rel always being valid when we need the
LockInfo? I'm OK with avoiding duplicating
rd_id/rd_lockinfo.lockRelId.relId, but I'm not sure dbId can always be
derived with rd_rel->relisshared whenever we need it.
> - 0005: Replaces the embedded partition key, descriptors, partition
> qual, validity flag, and memory contexts with one lazily allocated
> RelationPartitionInfo pointer.
> => sizeof(RelationData) == 264 bytes
I haven't worked on partitioning, so I'm not fully confident that this
has sufficiently low additional overhead to be worth applying.
> - 0006: Removes rd_fkeyvalid by using RELCACHE_FKEYLIST_NOT_LOADED as
> the initial state of rd_fkeylist. NIL continues to mean that the list
> was computed and no foreign keys were found. This patch is not strictly
> needed because it currently doesn't further reduce the size. The same we
> could with RelationPartitionInfo::partcheckvalid.
> => sizeof(RelationData) == 264 bytes
I'm not a fan of this change. Sentinel values *can* have their place,
but I really don't like non-NULL values being used to signal "invalid"
states, and seeing that it doesn't actually save any bytes I'd prefer
to not add this complication.
> - 0007: Removes rd_index member that always pointed inside
> rd_indextuple. Callers now use RelationGetIndex(), which applies
> GETSTRUCT() to that tuple.
> => sizeof(RelationData) == 256 bytes
This seems fine to me.
> - 0008: Adds a static assertion that sizeof(RelationData) <= 256.
> => sizeof(RelationData) == 256 bytes
I'm not a fan of this, because we generally don't add assertions on
struct sizes unless it's critically important a struct remains the
asserted size (or, in this case, doesn't become larger than that).
In this case, I don't think it's critically important that the struct
fits in the 256-byte aset bucket, given that relcache memory usage has
never been capped, and a slab context would similarly do the trick for
avoiding memory usage cliffs when the size of the struct is increased.
> Note that the necessity to arrive at 256 bytes stems from ASET's
> allocation granularity being powers of two. To profit from further size
> reductions of RelationData, we would need to use a SLAB memory context
> because it's unlikely that we'll get to 128 bytes.
Let's start with palloc-ing all RelationData into Slab contexts (like
attached, tagged with .nocfbot to avoid your patch's CI). This allows
us to start saving bytes immediately, and immediately improves memory
usage for every reduction in size so that the merits of each later
patch can be evaluated separately. This will be very useful if we
can't agree on some of the changes that are necessary to reduce the
size down to the next smaller aset size bucket.
Kind regards,
Matthias van de Meent
Databricks (https://www.databricks.com)
| Attachment | Content-Type | Size |
|---|---|---|
| v1-0001-relcache-Use-Slab-context-for-RelationData-allocs.nocfbot.patch | application/x-patch | 3.3 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Daniel Gustafsson | 2026-09-14 12:37:57 | Re: Does postgresql have a diff tool? |
| Previous Message | Graham Leggett | 2026-09-14 12:33:44 | Does postgresql have a diff tool? |