v1-fix-ginFinishSplit-lock.patch

application/octet-stream

Filename: v1-fix-ginFinishSplit-lock.patch
Type: application/octet-stream
Part: 0
Message: MarkBufferDirty Assert held LW_EXCLUSIVE lock fail when ginFinishSplit

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: unified
Series: patch v1
File+
src/backend/access/gin/ginbtree.c 14 2
diff --git a/src/backend/access/gin/ginbtree.c b/src/backend/access/gin/ginbtree.c
index 39e2c07ad3..4f6fcd4266 100644
--- a/src/backend/access/gin/ginbtree.c
+++ b/src/backend/access/gin/ginbtree.c
@@ -108,7 +108,16 @@ ginFindLeafPage(GinBtree btree, bool searchMode,
 		 * encounter on the way.
 		 */
 		if (!searchMode && GinPageIsIncompleteSplit(page))
-			ginFinishSplit(btree, stack, false, NULL);
+		{
+			if (access == GIN_SHARE)
+			{
+				/* for internal page, we should relock our page */
+				LockBuffer(stack->buffer, GIN_UNLOCK);
+				LockBuffer(stack->buffer, GIN_EXCLUSIVE);
+			}
+			if GinPageIsIncompleteSplit(page)
+				ginFinishSplit(btree, stack, false, NULL);
+		}
 
 		/*
 		 * ok, page is correctly locked, we should check to move right ..,
@@ -123,7 +132,10 @@ ginFindLeafPage(GinBtree btree, bool searchMode,
 				/* rightmost page */
 				break;
 
-			stack->buffer = ginStepRight(stack->buffer, btree->index, access);
+			if (!searchMode)
+				stack->buffer = ginStepRight(stack->buffer, btree->index, GIN_EXCLUSIVE);
+			else
+				stack->buffer = ginStepRight(stack->buffer, btree->index, access);
 			stack->blkno = rightlink;
 			page = BufferGetPage(stack->buffer);