Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vohuY-00CfhE-2W for pgsql-hackers@arkaria.postgresql.org; Sat, 07 Feb 2026 12:59:42 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vohuX-006i1b-20 for pgsql-hackers@arkaria.postgresql.org; Sat, 07 Feb 2026 12:59:41 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vohuX-006i1T-10 for pgsql-hackers@lists.postgresql.org; Sat, 07 Feb 2026 12:59:41 +0000 Received: from meesny.iki.fi ([195.140.195.201]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1vohuV-00000000zVC-0gUt for pgsql-hackers@postgresql.org; Sat, 07 Feb 2026 12:59:40 +0000 Received: from [10.0.2.15] (unknown [130.41.208.2]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange x25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: hlinnaka) by meesny.iki.fi (Postfix) with ESMTPSA id 4f7WJ70RYRzyQx; Sat, 07 Feb 2026 14:59:34 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=meesny; t=1770469175; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UELNtBYU8NTj8FvsIXjM8PHSgIh6wgF8BpuTIM4FP9g=; b=RtPmEb+qJkm1JcuvAKRijfPWnCG9+/97uhdGFcjzzsRmlbZYhrmzOGBeUw8CF4Dbo1rwkr BZGayLTtNhxUglEkYQ+OLBUgyRBAjQuGIG/Mj2uEG0lo3IDedTa2qFPQ3y03VQcpsh5gSv R22tgx3S487riK9bX+TeaC5K03Prp/k= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=meesny; t=1770469175; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UELNtBYU8NTj8FvsIXjM8PHSgIh6wgF8BpuTIM4FP9g=; b=DP75eRhNsCjXZwypnDA2frLwLGNVlDvE6lZBqthSQc/tzqwjpLdep3tHI5ICkt9nwdfcuC wUJU4VUFmNEMkvB535dSne+/gC6Ivy10MhdD/aROWKbZRKetbBdnoRdmrcIt+CCY4lH4+t MRXdQpsfw9VRDyzFhx6padyXLp0n6Vk= ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=hlinnaka smtp.mailfrom=hlinnaka@iki.fi ARC-Seal: i=1; a=rsa-sha256; d=iki.fi; s=meesny; cv=none; t=1770469175; b=P4z0Rk3GktxQJCqpsn3dlcWEUAXk1ptm4C5T3S8kQbr4vvYu3UWp94Z1z0yW1BSaoPo+Q7 dGjvA5dxLqkreaTqidE/qjztSQR7juBjOCK1No33Lepm5D6xGgt152FgGzPITUvAihIP5y LU6cmAPy2QTsTvufW0Hq3o0T/uIFldg= Message-ID: Date: Sat, 7 Feb 2026 14:59:34 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: Buffer locking is special (hints, checksums, AIO writes) To: Andres Freund , Melanie Plageman , Noah Misch Cc: Kirill Reshke , Matthias van de Meent , pgsql-hackers@postgresql.org, Thomas Munro , Robert Haas , Michael Paquier References: <1108f18d-cf7c-4f17-b29c-a119fe42f7e5@iki.fi> <5dwlfu2jyzkyf3nrlzxxblxctb6xio5es73ptgsahjnmfu5miu@772rc764hfhi> <4csodkvvfbfloxxjlkgsnl2lgfv2mtzdl7phqzd4jxjadxm4o5@usw7feyb5bzf> <5ubipyssiju5twkb7zgqwdr7q2vhpkpmuelxfpanetlk6ofnop@hvxb4g2amb2d> Content-Language: en-US From: Heikki Linnakangas In-Reply-To: <5ubipyssiju5twkb7zgqwdr7q2vhpkpmuelxfpanetlk6ofnop@hvxb4g2amb2d> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk 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