Re: Buffer locking is special (hints, checksums, AIO writes)
Chao Li <li.evan.chao@gmail.com>
> On Jan 16, 2026, at 00:43, Andres Freund <andres@anarazel.de> wrote:
>
> Hi,
>
> On 2026-01-15 14:22:09 +0800, Chao Li wrote:
>> 3 - 0005 - bufmgr.c
>> ```
>> +inline void
>> +MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
>> ```
>>
>> It’s quite uncommon to extern an inline function. I think usually if we want
>> to make an inline function accessible from external, we define it “static
>> inline” in a header file. So, I guess “inline” is a typo here.
>
> It works just fine to put an inline into the function definition, even if it's
> an external function. That hints the compiler to inline it inside the
> translation unit. Which is useful here, because it leads to
> MarkBufferDirtyHint() being inlined into BufferFinishSetHintBits().
>
Technically, that for sure works. I raised the comment basically because it’s uncommon in the source tree. I just did a search for “inline” across all .c files, only found two non-static inline functions: ReadBufferExtended() and TrackNewBufferPin(), and they are all in bufmgr.c. So, adding a new one should be fine. I should have done the search yesterday while reviewing.
>> 8 - 0005 - fsmpage.c
>> ```
>> * needs to be updated. exclusive_lock_held should be set to true if the
>> * caller is already holding an exclusive lock, to avoid extra work.
>> ```
>>
>> The function comment of fsm_search_avail() needs to be
>> updated. exclusive_lock_held should be set to true if the caller is already
>> holding a **share-exclusive or** exclusive lock.
>
> Why?
Ah, I see. We will never use a share-exclusive lock for fsm_search_avail? Currently, there are two callers of fsm_search_avail, one use a share lock, the other uses an exclusive lock. My bad.
>> 10 - 0005 - freespace.c
>> ```
>> - * Reset the next slot pointer. This encourages the use of low-numbered
>> - * pages, increasing the chances that a later vacuum can truncate the
>> - * relation. We don't bother with marking the page dirty if it wasn't
>> - * already, since this is just a hint.
>> + * Try to reset the next slot pointer. This encourages the use of
>> + * low-numbered pages, increasing the chances that a later vacuum can
>> + * truncate the relation. We don't bother with marking the page dirty if
>> + * it wasn't already, since this is just a hint.
>> */
>> LockBuffer(buf, BUFFER_LOCK_SHARE);
>> - ((FSMPage) PageGetContents(page))->fp_next_slot = 0;
>> + if (BufferBeginSetHintBits(buf))
>> + {
>> + ((FSMPage) PageGetContents(page))->fp_next_slot = 0;
>> + BufferFinishSetHintBits(buf, false, false);
>> + }
>> ```
>>
>> Before this patch, we unconditionally set fp_next_slot, now the setting
>> might be skipped. You have add “Try to” in the comment that has explained
>> the possibility of skipping setting fp_next_slot. Would it be better to add
>> a brief statement for what will result in when skipping setting
>> fp_next_slot? Something like “Skipping the update only affects reuse, not
>> correctness”.
>
> I don't see the point. The whole paragraph is about how this isn't crucial.
>
Yeah, I could understand the comment expresses that isn’t crucial, but just felt that’s not “explicit”. I am fine with the current comment.
Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/
Commits
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
bufmgr: Fix ordering of checks in PinBuffer()
- c0af4eb4e71e 19 (unreleased) landed
-
Use UnlockReleaseBuffer() in more places
- 8df3c48e466c 19 (unreleased) landed
-
bufmgr: Make UnlockReleaseBuffer() more efficient
- f39cb8c01106 19 (unreleased) landed
-
bufmgr: Don't copy pages while writing out
- 41d3d64e87af 19 (unreleased) landed
-
Fix use of wrong variable in _hash_kill_items()
- f5eb854ab6d6 19 (unreleased) landed
-
Fix bug due to confusion about what IsMVCCSnapshot means
- ce5d489166e5 19 (unreleased) landed
-
bufmgr: Switch to standard order in MarkBufferDirtyHint()
- a766125efd60 19 (unreleased) landed
-
bufmgr: Remove the, now obsolete, BM_JUST_DIRTIED
- b0f4ff3c9266 19 (unreleased) landed
-
Require share-exclusive lock to set hint bits and to flush
- 82467f627bd4 19 (unreleased) landed
-
heapam: Don't mimic MarkBufferDirtyHint() in inplace updates
- f4a4ce52c0d1 19 (unreleased) landed
-
bufmgr: Allow conditionally locking of already locked buffer
- 333f586372aa 19 (unreleased) landed
-
bufmgr: Avoid spurious compiler warning after fcb9c977aa5
- 84705b37273d 19 (unreleased) landed
-
lwlock: Remove ForEachLWLockHeldByMe
- 55fbfb738b00 19 (unreleased) landed
-
lwlock: Remove support for disowned lwlwocks
- d40fd85187d0 19 (unreleased) landed
-
bufmgr: Implement buffer content locks independently of lwlocks
- fcb9c977aa5f 19 (unreleased) landed
-
bufmgr: Change BufferDesc.state to be a 64-bit atomic
- dac328c8a682 19 (unreleased) landed
-
lwlock: Improve local variable name
- 556c92a68972 19 (unreleased) landed
-
lwlock: Invert meaning of LW_FLAG_RELEASE_OK
- 9a385f61666c 19 (unreleased) landed
-
bufmgr: Make definitions related to buffer descriptor easier to modify
- ff219c198789 19 (unreleased) landed
-
heapam: Add batch mode mvcc check and use it in page mode
- 0b96e734c590 19 (unreleased) landed
-
freespace: Don't modify page without any lock
- 45f658dacb9c 19 (unreleased) landed
-
heapam: Move logic to handle HEAP_MOVED into a helper function
- 548de59d93d5 19 (unreleased) landed
-
bufmgr: Optimize & harmonize LockBufHdr(), LWLockWaitListLock()
- 09ae2c8bac8d 19 (unreleased) landed
-
bufmgr: Add one-entry cache for private refcount
- 30df61990c67 19 (unreleased) landed
-
bufmgr: Separate keys for private refcount infrastructure
- edbaaea0a95e 19 (unreleased) landed
-
Add pg_atomic_unlocked_write_u64
- 7902a47c20b1 19 (unreleased) landed
-
Rename BUFFERPIN wait event class to BUFFER
- 6c5c393b7403 19 (unreleased) landed
-
bufmgr: Turn BUFFER_LOCK_* into an enum
- 156680055dc5 19 (unreleased) landed
-
lwlock: Fix, currently harmless, bug in LWLockWakeup()
- 81f773895321 19 (unreleased) landed
- da3971496531 15.16 landed
- 89c8a1b9069f 16.12 landed
- 427e886a79a5 17.8 landed
- 332693e75969 14.21 landed
- 8082b759d9b5 18.2 landed
-
bufmgr: Use atomic sub for unpinning buffers
- 5310fac6e0fc 19 (unreleased) landed
-
bufmgr: Allow some buffer state modifications while holding header lock
- c75ebc657ffc 19 (unreleased) landed
-
bufmgr: Fix valgrind checking for buffers pinned in StrategyGetBuffer()
- c819d1017ddb 19 (unreleased) landed
-
bufmgr: Don't lock buffer header in StrategyGetBuffer()
- 5e8998592879 19 (unreleased) landed
-
bufmgr: fewer calls to BufferDescriptorGetContentLock
- 3baae90013df 19 (unreleased) landed
-
bufmgr: Fix signedness of mask variable in BufferSync()
- 2a2e1b470b9b 19 (unreleased) landed
-
bufmgr: Introduce FlushUnlockedBuffer
- 3c2b97b29ee3 19 (unreleased) landed
-
Improve ReadRecentBuffer() scalability
- 819dc118c0f6 19 (unreleased) landed