| 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 |
| 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 |