Re: GetBufferDescriptor() being called for local buffers from MarkBufferDirtyHint()

From: Ayush Tiwari <ayushtiwari(dot)slg01(at)gmail(dot)com>
To: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>
Cc: Michael Paquier <michael(at)paquier(dot)xyz>, Andres Freund <andres(at)anarazel(dot)de>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: GetBufferDescriptor() being called for local buffers from MarkBufferDirtyHint()
Date: 2026-07-01 14:30:38
Message-ID: CAJTYsWUGEwwRXf6ye6cR0aA+eLANoRi0OhS2BzApKS96vUxb0w@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

On Wed, 1 Jul 2026 at 11:04, Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>
wrote:

> On Wed, Jul 1, 2026 at 12:47 AM Ayush Tiwari
> <ayushtiwari(dot)slg01(at)gmail(dot)com> wrote:
> > It looks like InitLocalBuffers() initializes the descriptors in a loop
> before
> > it sets NLocBuffer, so during that loop the assert sees NLocBuffer ==
> 0. The
> > access itself seems fine, since the array is already allocated with
> > num_temp_buffers entries; it's just that this is the one place that runs
> > before the bound the assert checks against is set. (The shared path
> doesn't
> > run into this, since NBuffers is already set when
> BufferManagerShmemInit()
> > does the equivalent loop.)
> >
> > I'm not sure which way would be preferable here if are adding assert for
> > LocalBufferDescriptor too:
> >
> > 1. set NLocBuffer = nbufs before the init loop, so the loop can keep
> using
> > GetLocalBufferDescriptor(); or
>
> This looks safe for me. The callers of InitLocalBuffers rely on
> LocalBufferHash to decide whether or not local buffers have been
> initialized. Further local buffers are local to the backend,
> concurrent access is not possible. So, even if we initialize
> NLocalBuffer before actually allocating the buffers, nobody is going
> to access the local buffers before they are fully initialized.
> LocalBufferHash still serves as a definitive condition to decide
> whether or not local buffers are initialized.
>

Thanks for looking! This matches my analysis as well.

>
> > 2. leave NLocBuffer where it is and index LocalBufferDescriptors[]
> directly
> > in that loop.
>
> I had suggested this in the context of shared buffers and it was shot
> down by Michael. So probably the same argument applies here.
>

Ahh I see, good to know it was already considered.

If 1 is not possible for some reason, you could augment your assertion
> as Assert(id >= 0 && (!LocalHashBuffers || id < NLocBuffer)) or
> separate the two operands of && into separate assertions.
>

I'm attaching a patch with option 1, ideally I would not want to
extend the assertion, but if the option is not feasible for some reason,
we'll have to go this way.

v2 attached sets NLocBuffer = nbufs before the initialization loop, so the
loop can keep using GetLocalBufferDescriptor(), and drops the now-redundant
assignment at the end.

Regards,
Ayush

Attachment Content-Type Size
v2-0001-Make-buffer-descriptor-accessors-take-signed-int.patch application/octet-stream 3.0 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Heikki Linnakangas 2026-07-01 14:43:50 Re: Adding REPACK [concurrently]
Previous Message Andrey Borodin 2026-07-01 14:18:12 Re: Relation bulk write facility