From 43d1ed60fdd96027f044e152176c0d45cd6bf443 Mon Sep 17 00:00:00 2001 From: Teodor Sigaev Date: Fri, 30 Mar 2018 14:23:17 +0300 Subject: Predicate locking in GIN index Predicate locks are used on per page basis only if fastupdate = off, in opposite case predicate lock on pending list will effectively lock whole index, to reduce locking overhead, just lock a relation. Entry and posting trees are essentially B-tree, so locks are acquired on leaf pages only. Author: Shubham Barai with some editorization by me and Dmitry Ivanov Review by: Alexander Korotkov, Dmitry Ivanov, Fedor Sigaev Discussion: https://www.postgresql.org/message-id/flat/CALxAEPt5sWW+EwTaKUGFL5_XFcZ0MuGBcyJ70oqbWqr42YKR8Q@mail.gmail.com --- src/backend/access/gin/ginbtree.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src/backend/access/gin/ginbtree.c') diff --git a/src/backend/access/gin/ginbtree.c b/src/backend/access/gin/ginbtree.c index 37070b3b729..095b1192cb4 100644 --- a/src/backend/access/gin/ginbtree.c +++ b/src/backend/access/gin/ginbtree.c @@ -17,6 +17,7 @@ #include "access/gin_private.h" #include "access/ginxlog.h" #include "access/xloginsert.h" +#include "storage/predicate.h" #include "miscadmin.h" #include "utils/memutils.h" #include "utils/rel.h" @@ -515,6 +516,19 @@ ginPlaceToPage(GinBtree btree, GinBtreeStack *stack, btree->fillRoot(btree, newrootpg, BufferGetBlockNumber(lbuffer), newlpage, BufferGetBlockNumber(rbuffer), newrpage); + + if (GinPageIsLeaf(BufferGetPage(stack->buffer))) + { + + PredicateLockPageSplit(btree->index, + BufferGetBlockNumber(stack->buffer), + BufferGetBlockNumber(lbuffer)); + + PredicateLockPageSplit(btree->index, + BufferGetBlockNumber(stack->buffer), + BufferGetBlockNumber(rbuffer)); + } + } else { @@ -524,6 +538,14 @@ ginPlaceToPage(GinBtree btree, GinBtreeStack *stack, GinPageGetOpaque(newrpage)->rightlink = savedRightLink; GinPageGetOpaque(newlpage)->flags |= GIN_INCOMPLETE_SPLIT; GinPageGetOpaque(newlpage)->rightlink = BufferGetBlockNumber(rbuffer); + + if (GinPageIsLeaf(BufferGetPage(stack->buffer))) + { + + PredicateLockPageSplit(btree->index, + BufferGetBlockNumber(stack->buffer), + BufferGetBlockNumber(rbuffer)); + } } /* -- cgit v1.2.3