public inbox for [email protected]  
help / color / mirror / Atom feed
From: Kirill Reshke <[email protected]>
To: pgsql-hackers <[email protected]>
Subject: Release and unpin buffers after leaving CRIT section in GIN.
Date: Tue, 17 Feb 2026 14:58:24 +0500
Message-ID: <CALdSSPgBPnpNNzxv0Y+_GNFzW6PmzRZYh+_hpf06Y1N2zLhZaQ@mail.gmail.com> (raw)

Hi
I have stopped $subj while doing unrelated hacking today.
transam/README suggest following for WAL-logging changes:

...

6. END_CRIT_SECTION()

7. Unlock and unpin the buffer(s).


Few places in GIN code does not follow that. v1 fixes it.

-- 
Best regards,
Kirill Reshke


Attachments:

  [application/octet-stream] v1-0001-Release-and-unpin-buffers-after-leaving-CRIT-sect.patch (4.2K, ../CALdSSPgBPnpNNzxv0Y+_GNFzW6PmzRZYh+_hpf06Y1N2zLhZaQ@mail.gmail.com/2-v1-0001-Release-and-unpin-buffers-after-leaving-CRIT-sect.patch)
  download | inline diff:
From c5edef91b479ddcd99be5fe500f7a10ec1b2ae8d Mon Sep 17 00:00:00 2001
From: reshke <[email protected]>
Date: Tue, 17 Feb 2026 09:53:27 +0000
Subject: [PATCH v1] Release and unpin buffers after leaving CRIT section in
 GIN.

This patches cleanup a few places in GIN code that
used to release and/or unpin buffers before leaving CRIT
section but not after. The latter is suggested by transam/README.
---
 src/backend/access/gin/gindatapage.c |  4 ++--
 src/backend/access/gin/ginfast.c     | 12 ++++++------
 src/backend/access/gin/gininsert.c   |  3 ++-
 src/backend/access/gin/ginutil.c     |  4 ++--
 src/backend/access/gin/ginvacuum.c   |  6 +++---
 5 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/src/backend/access/gin/gindatapage.c b/src/backend/access/gin/gindatapage.c
index 436e54f2066..c5d7db28077 100644
--- a/src/backend/access/gin/gindatapage.c
+++ b/src/backend/access/gin/gindatapage.c
@@ -1854,10 +1854,10 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
 		PageSetLSN(page, recptr);
 	}
 
-	UnlockReleaseBuffer(buffer);
-
 	END_CRIT_SECTION();
 
+	UnlockReleaseBuffer(buffer);
+
 	/* During index build, count the newly-added data page */
 	if (buildStats)
 		buildStats->nDataPages++;
diff --git a/src/backend/access/gin/ginfast.c b/src/backend/access/gin/ginfast.c
index 7a6b177977b..f50848eb65a 100644
--- a/src/backend/access/gin/ginfast.c
+++ b/src/backend/access/gin/ginfast.c
@@ -134,10 +134,10 @@ writeListPage(Relation index, Buffer buffer,
 	/* get free space before releasing buffer */
 	freesize = PageGetExactFreeSpace(page);
 
-	UnlockReleaseBuffer(buffer);
-
 	END_CRIT_SECTION();
 
+	UnlockReleaseBuffer(buffer);
+
 	return freesize;
 }
 
@@ -459,10 +459,10 @@ ginHeapTupleFastInsert(GinState *ginstate, GinTupleCollector *collector)
 	if (metadata->nPendingPages * GIN_PAGE_FREESIZE > cleanupSize * (Size) 1024)
 		needCleanup = true;
 
-	UnlockReleaseBuffer(metabuffer);
-
 	END_CRIT_SECTION();
 
+	UnlockReleaseBuffer(metabuffer);
+
 	/*
 	 * Since it could contend with concurrent cleanup process we cleanup
 	 * pending list not forcibly.
@@ -659,11 +659,11 @@ shiftList(Relation index, Buffer metabuffer, BlockNumber newHead,
 			}
 		}
 
+		END_CRIT_SECTION();
+
 		for (i = 0; i < data.ndeleted; i++)
 			UnlockReleaseBuffer(buffers[i]);
 
-		END_CRIT_SECTION();
-
 		for (i = 0; fill_fsm && i < data.ndeleted; i++)
 			RecordFreeIndexPage(index, freespace[i]);
 
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
index 0d63fb4ba27..c972848b29e 100644
--- a/src/backend/access/gin/gininsert.c
+++ b/src/backend/access/gin/gininsert.c
@@ -652,9 +652,10 @@ ginbuild(Relation heap, Relation index, IndexInfo *indexInfo)
 	MarkBufferDirty(RootBuffer);
 
 
+	END_CRIT_SECTION();
+
 	UnlockReleaseBuffer(MetaBuffer);
 	UnlockReleaseBuffer(RootBuffer);
-	END_CRIT_SECTION();
 
 	/* count the root as first entry page */
 	buildstate.buildStats.nEntryPages++;
diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c
index d205093e21d..ff927279cc3 100644
--- a/src/backend/access/gin/ginutil.c
+++ b/src/backend/access/gin/ginutil.c
@@ -663,9 +663,9 @@ ginUpdateStats(Relation index, const GinStatsData *stats, bool is_build)
 		PageSetLSN(metapage, recptr);
 	}
 
-	UnlockReleaseBuffer(metabuffer);
-
 	END_CRIT_SECTION();
+
+	UnlockReleaseBuffer(metabuffer);
 }
 
 /*
diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c
index 11a6674a10b..c9f143f6c31 100644
--- a/src/backend/access/gin/ginvacuum.c
+++ b/src/backend/access/gin/ginvacuum.c
@@ -224,12 +224,12 @@ ginDeletePage(GinVacuumState *gvs, BlockNumber deleteBlkno, BlockNumber leftBlkn
 		PageSetLSN(BufferGetPage(lBuffer), recptr);
 	}
 
+	END_CRIT_SECTION();
+
 	ReleaseBuffer(pBuffer);
 	ReleaseBuffer(lBuffer);
 	ReleaseBuffer(dBuffer);
 
-	END_CRIT_SECTION();
-
 	gvs->result->pages_newly_deleted++;
 	gvs->result->pages_deleted++;
 }
@@ -654,8 +654,8 @@ ginbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
 			PageRestoreTempPage(resPage, page);
 			MarkBufferDirty(buffer);
 			xlogVacuumPage(gvs.index, buffer);
-			UnlockReleaseBuffer(buffer);
 			END_CRIT_SECTION();
+			UnlockReleaseBuffer(buffer);
 		}
 		else
 		{
-- 
2.43.0



view thread (3+ 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]
  Subject: Re: Release and unpin buffers after leaving CRIT section in GIN.
  In-Reply-To: <CALdSSPgBPnpNNzxv0Y+_GNFzW6PmzRZYh+_hpf06Y1N2zLhZaQ@mail.gmail.com>

* 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