From 6e1baae9225bf48e8132cbd541c8e5ffd256e9d5 Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Tue, 17 Mar 2026 13:25:12 -0400 Subject: [PATCH v15 07/17] Add UnlockBufferGetLSN utility function. This combines the functionality of BufferGetLSNAtomic() with UnlockReleaseBuffer, with the option of not releasing buffer pin. --- src/include/storage/bufmgr.h | 1 + src/backend/access/index/indexbatch.c | 12 +------ src/backend/storage/buffer/bufmgr.c | 47 +++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h index 4017896f9..408d76c56 100644 --- a/src/include/storage/bufmgr.h +++ b/src/include/storage/bufmgr.h @@ -253,6 +253,7 @@ extern void WaitReadBuffers(ReadBuffersOperation *operation); extern void ReleaseBuffer(Buffer buffer); extern void UnlockReleaseBuffer(Buffer buffer); +extern XLogRecPtr UnlockBufferGetLSN(Buffer buffer, bool release); extern bool BufferIsLockedByMe(Buffer buffer); extern bool BufferIsLockedByMeInMode(Buffer buffer, BufferLockMode mode); extern bool BufferIsDirty(Buffer buffer); diff --git a/src/backend/access/index/indexbatch.c b/src/backend/access/index/indexbatch.c index 342727f2b..fe1651a7f 100644 --- a/src/backend/access/index/indexbatch.c +++ b/src/backend/access/index/indexbatch.c @@ -562,17 +562,7 @@ indexam_util_batch_unlock(IndexScanDesc scan, IndexScanBatch batch, Buffer buf) * Non-immediate-unguard scans retain the pin; the table AM will call * amunguardbatch to drop the interlock when ready. */ - batch->lsn = BufferGetLSNAtomic(buf); - if (scan->batchImmediateUnguard) - { - /* drop both the lock and the pin */ - UnlockReleaseBuffer(buf); - } - else - { - /* just drop the lock (hold on to interlock pin) */ - UnlockBuffer(buf); - } + batch->lsn = UnlockBufferGetLSN(buf, scan->batchImmediateUnguard); } else { diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 00bc60952..2a95517a3 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -5525,6 +5525,53 @@ UnlockReleaseBuffer(Buffer buffer) ReleaseBuffer(buffer); } +/* + * UnlockBufferGetLSN + * Read a buffer's LSN, then unlock the buffer. Optionally release the + * pin too. + * + * This combines the functionality of BufferGetLSNAtomic() with + * UnlockReleaseBuffer, with the option of not releasing buffer pin. + * + * Used to unlock a buffer lock (and possibly to release its pin) when held on + * an index page. This is needed frequently enough to justify specialization. + */ +XLogRecPtr +UnlockBufferGetLSN(Buffer buffer, bool release) +{ + BufferDesc *buf_hdr; + Page page; + XLogRecPtr lsn; + + Assert(BufferIsValid(buffer)); + Assert(BufferIsPinned(buffer)); + + if (BufferIsLocal(buffer)) + { + buf_hdr = GetLocalBufferDescriptor(-buffer - 1); + page = (Page) LocalBufHdrGetBlock(buf_hdr); + lsn = PageGetLSN(page); + if (release) + UnpinLocalBuffer(buffer); + return lsn; + } + + buf_hdr = GetBufferDescriptor(buffer - 1); + page = (Page) BufHdrGetBlock(buf_hdr); + +#ifdef PG_HAVE_8BYTE_SINGLE_COPY_ATOMICITY + lsn = PageGetLSN(page); +#else + lsn = BufferGetLSNAtomic(buffer); +#endif + + BufferLockUnlock(buffer, buf_hdr); + if (release) + UnpinBuffer(buf_hdr); + + return lsn; +} + /* * IncrBufferRefCount * Increment the pin count on a buffer that we have *already* pinned -- 2.53.0