Re: Buffer locking is special (hints, checksums, AIO writes)

From: Andres Freund <andres(at)anarazel(dot)de>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Peter Geoghegan <pg(at)bowt(dot)ie>
Cc: Alexander Lakhin <exclusion(at)gmail(dot)com>, Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com>, Kirill Reshke <reshkekirill(at)gmail(dot)com>, Heikki Linnakangas <hlinnaka(at)iki(dot)fi>, Melanie Plageman <melanieplageman(at)gmail(dot)com>, Matthias van de Meent <boekewurm+postgres(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org, Thomas Munro <thomas(dot)munro(at)gmail(dot)com>, Noah Misch <noah(at)leadboat(dot)com>, Robert Haas <robertmhaas(at)gmail(dot)com>, Michael Paquier <michael(dot)paquier(at)gmail(dot)com>
Subject: Re: Buffer locking is special (hints, checksums, AIO writes)
Date: 2026-01-29 17:27:10
Message-ID: q2o7rfmkcvqhj7ttimno33mb7lklybj6aanliertmfr4g7g7zn@w4cat7zimc5c
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

On 2026-01-24 19:54:36 -0500, Tom Lane wrote:
> Andres Freund <andres(at)anarazel(dot)de> writes:
> > On 2026-01-24 16:11:47 -0500, Tom Lane wrote:
> >> In the case at hand I think it is probably driven by two recursion levels
> >> trying to acquire free space out of the same buffer. SPGist is expecting
> >> the lower level to fail to get the lock and then go find some free space
> >> elsewhere. Yeah, we could probably re-code it to get that outcome in
> >> another way, but why?
>
> > Regardless of the assertion, it still feels like there may be something off
> > here. Why is the page marked as empty in the FSM, despite actually not being
> > empty?
>
> Who said anything about its being empty?

In the crashes due to Alexander's repro that I have looked at, the page is
returned by SpGistNewBuffer()->GetFreeIndexPage(). Which afaict should only
contain empty pages. It's easy to see how that could happen with concurrency,
but there's none in the test.

I was just trying to repro this again while writing this message, and
interestingly I got the same issue in nbtree this time. Which a) confirms
Peter's statement that the "conditionally locking a buffer we already locked"
issue exists for nbtree b) makes me suspect something odd is happening around
indexfsm.

Anyway, independent of that, the behavior clearly needs to be allowed. Here's
a proposed patch.

At first I was thinking of just removing the assertion without anything else
in place - but I think that's not quite right: We could e.g. be trying to
acquire a share or share-exclusive lock when holding a share lock (or the
reverse), but we can't currently don't keep track of two different lock modes
for the same lock. Therefore it seems safer to just define it so that
acquiring a conditional lock on a buffer that is already locked by us will
always fail, regardless of what existing lock mode we already hold. I think
all current callers good with that.

Does that sound reasonable?

We could add support for locking the same buffer multiple times, but I don't
think it'd be worth the complexity and (small) overhead that would bring with
it? It also seems like allowing that would make it more likely for a backend
to trample over its own state higher up in the call tree.

Greetings,

Andres Freund

Attachment Content-Type Size
v1-0001-bufmgr-Allow-conditionally-locking-of-already-loc.patch.txt text/plain 2.0 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Andres Freund 2026-01-29 17:42:41 Re: Buffer locking is special (hints, checksums, AIO writes)
Previous Message Bear Giles 2026-01-29 17:15:35 Follow-up on OpenSSL "engines" and "providers"