public inbox for [email protected]  
help / color / mirror / Atom feed
From: Heikki Linnakangas <[email protected]>
To: Andres Freund <[email protected]>
To: Melanie Plageman <[email protected]>
To: Noah Misch <[email protected]>
Cc: Kirill Reshke <[email protected]>
Cc: Matthias van de Meent <[email protected]>
Cc: [email protected]
Cc: Thomas Munro <[email protected]>
Cc: Robert Haas <[email protected]>
Cc: Michael Paquier <[email protected]>
Subject: Re: Buffer locking is special (hints, checksums, AIO writes)
Date: Sat, 7 Feb 2026 14:59:34 +0200
Message-ID: <[email protected]> (raw)
In-Reply-To: <5ubipyssiju5twkb7zgqwdr7q2vhpkpmuelxfpanetlk6ofnop@hvxb4g2amb2d>
References: <q3ybyaiownp4ivt6xfy55s5llvtq6vqsd4zbt5kn6hacxdcpp4@2ngd4h4bev5d>
	<dsbacri4xldlobl3jbqqlksefsyrwj7lzljbohxsbqjus3z4o7@otb6rge4w7az>
	<[email protected]>
	<5dwlfu2jyzkyf3nrlzxxblxctb6xio5es73ptgsahjnmfu5miu@772rc764hfhi>
	<ossv2eistssmubfsir6xjll76tynvxv5lup4zkrfzjkud7fycw@rf5vii6l6cha>
	<4csodkvvfbfloxxjlkgsnl2lgfv2mtzdl7phqzd4jxjadxm4o5@usw7feyb5bzf>
	<CALdSSPgyc7VuMLUZ8J7v2G-PebBa_vEi+mp-cLkcOwNycB56Hw@mail.gmail.com>
	<kjdgvws34gpnz4y6xu5aaeul5mspgy3ahvyiw4lndb3ecsacdb@b2ccyowotpqh>
	<jtg5cu4n6h5lib3kzx66ju4yhh6kmviaud7oq6dtut6c4q4rdi@xwsfoagt3c2b>
	<k5j77f3q6ztihnjnx2nqxzyor6fbj2qxcbhzuxhkh2yy63jyfg@p72phigar3n4>
	<5ubipyssiju5twkb7zgqwdr7q2vhpkpmuelxfpanetlk6ofnop@hvxb4g2amb2d>

A few minor nitpicks on v12 below. Other than these and the comments I 
wrote in separate emails, looks good to me.

> @@ -371,8 +382,6 @@ _bt_killitems(IndexScanDesc scan)
>         }
>  
>         /*
> -        * Since this can be redone later if needed, mark as dirty hint.
> -        *
>          * Whenever we mark anything LP_DEAD, we also set the page's
>          * BTP_HAS_GARBAGE flag, which is likewise just a hint.  (Note that we
>          * only rely on the page-level flag in !heapkeyspace indexes.)

Seems a bit random to remove that.

> +/*
> + * Try to set a single hint bit in a buffer.
> + *
> + * This is a bit faster than BufferBeginSetHintBits() /
> + * BufferFinishSetHintBits() when setting a single hint bit, but slower than
> + * the former when setting several hint bits.
> + */
> +bool
> +BufferSetHintBits16(uint16 *ptr, uint16 val, Buffer buffer)

This could use some more explanation. The point is that this does "*ptr 
= val", if it's allowed to set hint bits. That's not obvious. And 
"single hint bit" isn't really accurate, as you could update multiple 
bits in *ptr with one call.

> 	/*
> 	 * If the buffer was dirty, try to write it out.  There is a race
> 	 * condition here, in that someone might dirty it after we released the
> 	 * buffer header lock above.  We will recheck the dirty bit after
> 	 * re-locking the buffer header.
> 	 */

It's not clear what "above" means in that paragraph. Where do we release 
the buffer header lock? In StrategyGetBuffer?

(This is not actually new with this patch; it goes back to commit 
5e89985928. Before that, there was a call to PinBuffer_Locked() which 
released the spinlock.)

> @@ -2516,18 +2515,21 @@ again:
>                 /*
>                  * If using a nondefault strategy, and writing the buffer would
>                  * require a WAL flush, let the strategy decide whether to go ahead
> -                * and write/reuse the buffer or to choose another victim.  We need a
> -                * lock to inspect the page LSN, so this can't be done inside
> +                * and write/reuse the buffer or to choose another victim.  We need to
> +                * hold the content lock in at least share-exclusive mode to safely
> +                * inspect the page LSN, so this couldn't have been done inside
>                  * StrategyGetBuffer.
>                  */
>                 if (strategy != NULL)
>                 {
>                         XLogRecPtr      lsn;
>  
> -                       /* Read the LSN while holding buffer header lock */
> -                       buf_state = LockBufHdr(buf_hdr);
> +                       /*
> +                        * As we now hold at least a share-exclusive lock on the buffer,
> +                        * the LSN cannot change during the flush (and thus can't be
> +                        * torn).
> +                        */
>                         lsn = BufferGetLSN(buf_hdr);
> -                       UnlockBufHdr(buf_hdr);
>  
>                         if (XLogNeedsFlush(lsn)
>                                 && StrategyRejectBuffer(strategy, buf_hdr, from_ring))

I think the second comment is redundant with the first one. Let's just 
remove it.

> +/*
> + * Helper for BufferBeginSetHintBits() and BufferSetHintBits16().
> + *
> + * This checks if the current lock mode already suffices to allow hint bits
> + * being set and, if not, whether the current lock can be upgraded.
> + *
> + * Updates *lockstate when returning true.
> + */
> +static inline bool
> +SharedBufferBeginSetHintBits(Buffer buffer, BufferDesc *buf_hdr, uint64 *lockstate)

Would be good to be more explicit what returning true/false here means.

- Heikki







view thread (35+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]
  Subject: Re: Buffer locking is special (hints, checksums, AIO writes)
  In-Reply-To: <[email protected]>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox