Re: Making the initial and maximum DSA segment sizes configurable

From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: Tomas Vondra <tomas(dot)vondra(at)enterprisedb(dot)com>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, John Naylor <johncnaylorls(at)gmail(dot)com>
Subject: Re: Making the initial and maximum DSA segment sizes configurable
Date: 2024-02-29 02:47:51
Message-ID: CAD21AoBGQ3QggMxer88Kg9xqYhv8yj+OudZukyuvE_M27rkPLg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

Thank you for the comments!

On Mon, Feb 26, 2024 at 6:58 AM Tomas Vondra
<tomas(dot)vondra(at)enterprisedb(dot)com> wrote:
>
> Hello Masahiko-san,
>
> I'm not super-familiar with the DSA/DSM stuff, but I think your proposal
> makes sense.
>
> I agree with your observation that DSA is a bit like AllocSet, so if
> that allows specifying min/max block size, maybe DSA should allow the
> same thing for segments ...
>
> However, does it actually address the problem you've described? If I
> understand it correctly, the problem is that with the doubling logic,
> we're likely to overshoot the limit. For example with m_w_m=512MB we
> first undershoot it a bit (510MB), and then overshoot it a lot (766MB).
> Which is not great, I agree (especially the overshooting).
>
> But is the modification you propose much better? I mean, we still
> overshoot the limit, right? By a smaller amount (just 62MB instead of
> 254MB), but it's still more than the limit ...
>
> Moreover, this really depend on the caller using lower init/max segment
> size, right? I'd bet most places would just hard-code something, which
> means it won't respond to changes in the m_w_m value.
>
>
> Could instead allow specifying the expected size / memory limit,
> calculate the maximum segment size in DSA code, and also modify how the
> segment size evolves over time to decrease as we get closer to the
> expected size / limit?
>
> For example, let's say we'd create DSA with 512MB limit. Then we could
> do this:
>
> 1MB, 2MB, 4MB, ..., 128MB, 256MB, 1MB, 1MB, ...
>
> because after 256MB we have 511MB of segments (in total), and we have to
> go all the way back to the smallest segment to not exceed the limit (or
> to minimize how much we exceed it). If the limit was set to 600MB, we'd
> go back to 64MB, then 16MB, etc.

Interesting idea. In fact, since we use each segment size two times,
we would do like:

1MB, 1MB, 2MB, 2MB, ... 128MB, 128MB = 510MB (continue)

then, back to the smallest segment:

2MB, 1MB = 513MB (stop)

With 600MB limit, we would do like:

1MB, 1MB, 2MB, 2MB, ... 128MB, 128MB = 510MB (continue)
64MB + 16MB + 8MB + 2MB + 1MB = 601MB (stop)

>
> Or maybe we could be smarter and calculate an "optimal point" at which
> point to start decreasing the segment size, roughly half-way through. So
> we'd end up with something like
>
> 1MB, 2MB, 4MB, ..., 128MB, 128MB, 64MB, 32MB, 16MB, ..., 1MB

I remember John proposed a similar idea[1]. Quoting from the email:

m_w_m = 1GB, so calculate the soft limit to be 512MB and pass it to
the DSA area.

2*(1+2+4+8+16+32+64+128) + 256 = 766MB (74.8% of 1GB) -> hit soft limit, so
"stairstep down" the new segment sizes:

766 + 2*(128) + 64 = 1086MB -> stop

Both are interesting ideas. The reason why I proposed the idea is the
simplicity; it is simple and a similar usage as aset.c.

I guess the latter idea (a soft limit idea) might also be implemented
in a simple way. It's worth trying it.

>
> But maybe that's unnecessarily complicated ... or maybe I'm missing some
> details that make this impossible for the DSA/DSM code.
>
> FWIW the aset.c code has the same problem - it's not aware of limits
> like work_mem / maintenance_work_mem, and with hard-coded limits we may
> easily hit exceed those (if we get to sufficiently large blocks,
> although in most cases the max block is 8MB, which limits how much we
> overshoot the limit). Not sure if that's an issue in practice, maybe the
> virtual memory thing deals with this for us.

Right, we use 8MB max block size in most cases and it works in aset.c.
On the other hand, since dsm.c has the limits on total number of
segments, we cannot use unnecessarily small segments.

>
> If you choose to go with passing the min/max segment size to DSA, maybe
> this should do a similar thing to aset.c and define a couple "good"
> values (like ALLOCSET_DEFAULT_SIZES, ALLOCSET_SMALL_SIZES, ...) and/or a
> macro to calculate good segment sizes for a given limit.

Agreed.

>
> Also, there's a comment:
>
> * See dsa_create() for a note about the tranche arguments.
>
> which should probably reference dsa_create_extended() instead.

Thanks, will fix it.

Regards,

[1] https://www.postgresql.org/message-id/CAFBsxsGiiyY%2BwykVLBbN9hFUMiNHqEr_Kqg9Mpc%3Duv4sg8eagQ%40mail.gmail.com

--
Masahiko Sawada
Amazon Web Services: https://aws.amazon.com

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Peter Smith 2024-02-29 02:59:19 Re: Synchronizing slots from primary to standby
Previous Message Kyotaro Horiguchi 2024-02-29 01:59:44 Re: MultiXact\SLRU buffers configuration