aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Korotkov <akorotkov@postgresql.org>2018-12-27 04:10:51 +0300
committerAlexander Korotkov <akorotkov@postgresql.org>2018-12-27 04:20:21 +0300
commitfd7c081955929df343318d6c5d32ea24a574aacf (patch)
tree5cefc66e3b61f574051583b2fbe01d8f3ef38e19
parentb30b9dce1f40499949fd3749265acf1b379102dc (diff)
downloadpostgresql-fd7c081955929df343318d6c5d32ea24a574aacf.tar.gz
postgresql-fd7c081955929df343318d6c5d32ea24a574aacf.zip
Remove entry tree root conflict checking from GIN predicate locking
According to README we acquire predicate locks on entry tree leafs and posting tree roots. However, when ginFindLeafPage() is going to lock leaf in exclusive mode, then it checks root for conflicts regardless whether it's a entry or posting tree. Assuming that we never place predicate lock on entry tree root (excluding corner case when root is leaf), this check is redundant. This commit removes this check. Now, root conflict checking is controlled by separate argument of ginFindLeafPage(). Discussion: https://postgr.es/m/CAPpHfdv7rrDyy%3DMgsaK-L9kk0AH7az0B-mdC3w3p0FSb9uoyEg%40mail.gmail.com Author: Alexander Korotkov Backpatch-through: 11
-rw-r--r--src/backend/access/gin/ginbtree.c8
-rw-r--r--src/backend/access/gin/gindatapage.c4
-rw-r--r--src/backend/access/gin/ginget.c4
-rw-r--r--src/backend/access/gin/gininsert.c2
-rw-r--r--src/include/access/gin_private.h3
5 files changed, 13 insertions, 8 deletions
diff --git a/src/backend/access/gin/ginbtree.c b/src/backend/access/gin/ginbtree.c
index 030d0f44183..78213dcb4ef 100644
--- a/src/backend/access/gin/ginbtree.c
+++ b/src/backend/access/gin/ginbtree.c
@@ -72,9 +72,13 @@ ginTraverseLock(Buffer buffer, bool searchMode)
* If 'searchmode' is false, on return stack->buffer is exclusively locked,
* and the stack represents the full path to the root. Otherwise stack->buffer
* is share-locked, and stack->parent is NULL.
+ *
+ * If 'rootConflictCheck' is true, tree root is checked for serialization
+ * conflict.
*/
GinBtreeStack *
-ginFindLeafPage(GinBtree btree, bool searchMode, Snapshot snapshot)
+ginFindLeafPage(GinBtree btree, bool searchMode,
+ bool rootConflictCheck, Snapshot snapshot)
{
GinBtreeStack *stack;
@@ -84,7 +88,7 @@ ginFindLeafPage(GinBtree btree, bool searchMode, Snapshot snapshot)
stack->parent = NULL;
stack->predictNumber = 1;
- if (!searchMode)
+ if (rootConflictCheck)
CheckForSerializableConflictIn(btree->index, NULL, stack->buffer);
for (;;)
diff --git a/src/backend/access/gin/gindatapage.c b/src/backend/access/gin/gindatapage.c
index 9f20513811e..54d68909125 100644
--- a/src/backend/access/gin/gindatapage.c
+++ b/src/backend/access/gin/gindatapage.c
@@ -1913,7 +1913,7 @@ ginInsertItemPointers(Relation index, BlockNumber rootBlkno,
{
/* search for the leaf page where the first item should go to */
btree.itemptr = insertdata.items[insertdata.curitem];
- stack = ginFindLeafPage(&btree, false, NULL);
+ stack = ginFindLeafPage(&btree, false, true, NULL);
ginInsertValue(&btree, stack, &insertdata, buildStats);
}
@@ -1932,7 +1932,7 @@ ginScanBeginPostingTree(GinBtree btree, Relation index, BlockNumber rootBlkno,
btree->fullScan = true;
- stack = ginFindLeafPage(btree, true, snapshot);
+ stack = ginFindLeafPage(btree, true, false, snapshot);
return stack;
}
diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c
index 8466d947eab..6bfe18c359f 100644
--- a/src/backend/access/gin/ginget.c
+++ b/src/backend/access/gin/ginget.c
@@ -338,7 +338,7 @@ restartScanEntry:
ginPrepareEntryScan(&btreeEntry, entry->attnum,
entry->queryKey, entry->queryCategory,
ginstate);
- stackEntry = ginFindLeafPage(&btreeEntry, true, snapshot);
+ stackEntry = ginFindLeafPage(&btreeEntry, true, false, snapshot);
page = BufferGetPage(stackEntry->buffer);
/* ginFindLeafPage() will have already checked snapshot age. */
@@ -679,7 +679,7 @@ entryLoadMoreItems(GinState *ginstate, GinScanEntry entry,
OffsetNumberNext(GinItemPointerGetOffsetNumber(&advancePast)));
}
entry->btree.fullScan = false;
- stack = ginFindLeafPage(&entry->btree, true, snapshot);
+ stack = ginFindLeafPage(&entry->btree, true, false, snapshot);
/* we don't need the stack, just the buffer. */
entry->buffer = stack->buffer;
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
index 5281eb68238..2781d3fdd83 100644
--- a/src/backend/access/gin/gininsert.c
+++ b/src/backend/access/gin/gininsert.c
@@ -195,7 +195,7 @@ ginEntryInsert(GinState *ginstate,
ginPrepareEntryScan(&btree, attnum, key, category, ginstate);
- stack = ginFindLeafPage(&btree, false, NULL);
+ stack = ginFindLeafPage(&btree, false, false, NULL);
page = BufferGetPage(stack->buffer);
if (btree.findItem(&btree, stack))
diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h
index 81bf8734ce3..bca82463199 100644
--- a/src/include/access/gin_private.h
+++ b/src/include/access/gin_private.h
@@ -195,7 +195,8 @@ typedef struct
* PostingItem
*/
-extern GinBtreeStack *ginFindLeafPage(GinBtree btree, bool searchMode, Snapshot snapshot);
+extern GinBtreeStack *ginFindLeafPage(GinBtree btree, bool searchMode,
+ bool rootConflictCheck, Snapshot snapshot);
extern Buffer ginStepRight(Buffer buffer, Relation index, int lockmode);
extern void freeGinBtreeStack(GinBtreeStack *stack);
extern void ginInsertValue(GinBtree btree, GinBtreeStack *stack,