Re: Buffer locking is special (hints, checksums, AIO writes)
Heikki Linnakangas <hlinnaka@iki.fi>
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
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