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

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

Hi,

On Mon, 29 Jun 2026 at 13:29, Ayush Tiwari <ayushtiwari(dot)slg01(at)gmail(dot)com>
wrote:

>
> Given the discussion here, I tried making the buffer descriptor accessors
> take
> a signed index and adding range assertions.
>
> Most callers already pass signed buffer indexes derived from Buffer values
> (e.g. buffer - 1, or -buffer - 1 for local buffers). The only caller I
> found
> that passes an unsigned value to GetBufferDescriptor() is
> ClockSweepTick(), and
> that normalizes the value before returning it, so it should still be less
> than
> NBuffers.
>
> The change looked fairly straightforward to me, unless I'm missing
> something.
> I also made the same change for GetLocalBufferDescriptor(), since it has
> the
> same uint32 signature and takes local buffer indexes.
>

cfbot flagged v1 in an assertion-enabled (cassert) build: anything that
uses a
temporary table hits the new assertion in GetLocalBufferDescriptor():

TRAP: failed Assert("id >= 0 && id < NLocBuffer"), buf_internals.h
GetLocalBufferDescriptor
InitLocalBuffers
ExtendBufferedRelLocal -> ... -> heap_insert

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
2. leave NLocBuffer where it is and index LocalBufferDescriptors[]
directly
in that loop.

Regards,
Ayush

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Pavel Stehule 2026-06-30 19:29:05 Re: Global temporary tables
Previous Message Mario González Troncoso 2026-06-30 18:28:14 Re: psql tab completion for user functions and if explicitly required also "pg_"