Re: Separate memory contexts for relcache and catcache

From: Andres Freund <andres(at)anarazel(dot)de>
To: Jeff Davis <pgsql(at)j-davis(dot)com>
Cc: Melih Mutlu <m(dot)melihmutlu(at)gmail(dot)com>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>, torikoshia <torikoshia(at)oss(dot)nttdata(dot)com>, vignesh C <vignesh21(at)gmail(dot)com>
Subject: Re: Separate memory contexts for relcache and catcache
Date: 2024-11-01 22:48:36
Message-ID: dywwv6v6vq3wfqyebypspq7kuez44tnycbvqjspgsqypuunbzn@mzixkn6g47y2
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

On 2024-11-01 14:47:37 -0700, Jeff Davis wrote:
> On Fri, 2024-11-01 at 15:19 -0400, Andres Freund wrote:
> > I'm a bit worried about the increase in "wasted" memory we might end
> > up when
> > creating one aset for *everything*. Just splitting out Relcache and
> > CatCache
> > isn't a big deal from that angle, they're always used reasonably
> > much. But
> > creating a bunch of barely used contexts does have the potential for
> > lots of
> > memory being wasted at the end of a page and on freelists.  It might
> > be ok as
> > far was what you proposed in the above email, I haven't analyzed that
> > in depth
> > yet.
>
> Melih raised similar concerns. The new contexts that my patch created
> were CatCacheContext, RelCacheContext, SPICacheContext,
> PgOutputContext, PlanCacheContext, TextSearchCacheContext, and
> TypCacheContext.
>
> Those are all created lazily, so you need to at least be using the
> relevant feature before it has any cost (with the exception of the
> first two).

Well, you can't get very far without using at least CatCacheContext,
RelCacheContext, PlanCacheContext, TypCacheContext. The others are indeed much
more specific and not really worth worrying about.

> > > I agree with others that we should look at changing the initial
> > > size or
> > > type of the contexts, but that should be a separate commit.
> >
> > It needs to be done close together though, otherwise we'll increase
> > the
> > new-connection-memory-usage of postgres measurably.
>
> I don't have a strong opinion here; that was a passing comment. But I'm
> curious: why it would increase the per-connection memory usage much to
> just have a couple new memory contexts?

"much" is maybe too strong. But the memory usage in a new connection is fairly
low, it doesn't take a large increase to be noticeable percentage-wise. And
given how much people love having poolers full of idle connections, it shows
up in aggregate.

> > I've previously proposed creating a type of memory context that's
> > intended for
> > places where we never expect to allocate much which allocates from
> > either a
> > superior memory context or just from the system allocator and tracks
> > memory
> > via linked lists.
>
> Why not just use ALLOCSET_SMALL_SIZES?

That helps some, but not *that* much. You still end up with a bunch of partially
filled blocks. Here's e.g. an excerpt with your patch applied:

│ name │ ident │ type │ level │ path │ total_bytes │ total_nblocks │ free_bytes │ free_chunks │ used_bytes │
├──────────────────────────────┼────────────────────────────────────────────────┼──────────┼───────┼───────────────┼─────────────┼───────────────┼────────────┼─────────────┼────────────┤
│ CacheMemoryContext │ (null) │ AllocSet │ 2 │ {1,19} │ 8192 │ 1 │ 7952 │ 0 │ 240 │
│ TypCacheContext │ (null) │ AllocSet │ 3 │ {1,19,28} │ 8192 │ 1 │ 4816 │ 0 │ 3376 │
│ search_path processing cache │ (null) │ AllocSet │ 3 │ {1,19,29} │ 8192 │ 1 │ 5280 │ 7 │ 2912 │
│ CatCacheContext │ (null) │ AllocSet │ 3 │ {1,19,30} │ 262144 │ 6 │ 14808 │ 0 │ 247336 │
│ RelCacheContext │ (null) │ AllocSet │ 3 │ {1,19,31} │ 262144 │ 6 │ 8392 │ 2 │ 253752 │
│ relation rules │ pg_backend_memory_contexts │ AllocSet │ 4 │ {1,19,31,34} │ 8192 │ 4 │ 3280 │ 1 │ 4912 │
│ index info │ manyrows_pkey │ AllocSet │ 4 │ {1,19,31,35} │ 2048 │ 2 │ 864 │ 1 │ 1184 │
│ index info │ pg_statistic_ext_relid_index │ AllocSet │ 4 │ {1,19,31,36} │ 2048 │ 2 │ 928 │ 1 │ 1120 │
│ index info │ pg_class_tblspc_relfilenode_index │ AllocSet │ 4 │ {1,19,31,37} │ 2048 │ 2 │ 440 │ 1 │ 1608 │

(this is a tiny bit misleading as "search_path processing cache" was just moved")

You can quickly see that the various contexts have a decent amount of free
space, some of their space.

We've already been more aggressive about using separate contets for indexes -
and in aggregate that memory usage shows up:

postgres[1088243][1]=# SELECT count(*), sum(total_bytes) as total_bytes, sum(total_nblocks) as total_nblocks, sum(free_bytes) free_bytes, sum(free_chunks) as free_chunks, sum(used_bytes) used_bytes FROM pg_backend_memory_contexts WHERE path @> (SELECT path FROM pg_backend_memory_contexts WHERE name = 'CacheMemoryContext') and name = 'index info'
┌───────┬─────────────┬───────────────┬────────────┬─────────────┬────────────┐
│ count │ total_bytes │ total_nblocks │ free_bytes │ free_chunks │ used_bytes │
├───────┼─────────────┼───────────────┼────────────┼─────────────┼────────────┤
│ 87 │ 162816 │ 144 │ 48736 │ 120 │ 114080 │
└───────┴─────────────┴───────────────┴────────────┴─────────────┴────────────┘

And it's not just the partially filled blocks that are an "issue", it's also
the freelists that are much less likely to be used soon if they're split very
granularly. Often we'll end up with memory in freelists that are created while
building some information that then will not be used again.

Without your patch:
┌────────────────────┬────────────────────────────────────────────────┬──────────┬───────┬────────────┬─────────────┬───────────────┬────────────┬─────────────┬────────────┐
│ name │ ident │ type │ level │ path │ total_bytes │ total_nblocks │ free_bytes │ free_chunks │ used_bytes │
├────────────────────┼────────────────────────────────────────────────┼──────────┼───────┼────────────┼─────────────┼───────────────┼────────────┼─────────────┼────────────┤
│ CacheMemoryContext │ (null) │ AllocSet │ 2 │ {1,17} │ 524288 │ 7 │ 75448 │ 0 │ 448840 │
│ relation rules │ pg_backend_memory_contexts │ AllocSet │ 3 │ {1,17,27} │ 8192 │ 4 │ 3472 │ 4 │ 4720 │
...

Greetings,

Andres Freund

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Melanie Plageman 2024-11-01 23:35:22 Eagerly scan all-visible pages to amortize aggressive vacuum
Previous Message Tom Lane 2024-11-01 22:27:53 Re: Using Expanded Objects other than Arrays from plpgsql