diff options
author | Teodor Sigaev <teodor@sigaev.ru> | 2018-03-27 15:43:19 +0300 |
---|---|---|
committer | Teodor Sigaev <teodor@sigaev.ru> | 2018-03-27 15:43:19 +0300 |
commit | 3ad55863e9392bff73377911ebbf9760027ed405 (patch) | |
tree | b3629aa316822f1bff9003b85244a27cbb14449f /src/backend/access/gist | |
parent | 4b9094eb6e14dfdbed61278ea8e51cc846e43579 (diff) | |
download | postgresql-3ad55863e9392bff73377911ebbf9760027ed405.tar.gz postgresql-3ad55863e9392bff73377911ebbf9760027ed405.zip |
Add predicate locking for GiST
Add page-level predicate locking, due to gist's code organization, patch seems
close to trivial: add check before page changing, add predicate lock before page
scanning. Although choosing right place to check is not simple: it should not
be called during index build, it should support insertion of new downlink and so
on.
Author: Shubham Barai with editorization by me and Alexander Korotkov
Reviewed by: Alexander Korotkov, Andrey Borodin, me
Discussion: https://www.postgresql.org/message-id/flat/CALxAEPtdcANpw5ePU3LvnTP8HCENFw6wygupQAyNBgD-sG3h0g@mail.gmail.com
Diffstat (limited to 'src/backend/access/gist')
-rw-r--r-- | src/backend/access/gist/gist.c | 13 | ||||
-rw-r--r-- | src/backend/access/gist/gistget.c | 3 |
2 files changed, 15 insertions, 1 deletions
diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index 51c32e4afee..52c83b9cbf5 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -18,6 +18,8 @@ #include "access/gistscan.h" #include "catalog/pg_collation.h" #include "miscadmin.h" +#include "storage/lmgr.h" +#include "storage/predicate.h" #include "nodes/execnodes.h" #include "utils/builtins.h" #include "utils/index_selfuncs.h" @@ -70,7 +72,7 @@ gisthandler(PG_FUNCTION_ARGS) amroutine->amsearchnulls = true; amroutine->amstorage = true; amroutine->amclusterable = true; - amroutine->ampredlocks = false; + amroutine->ampredlocks = true; amroutine->amcanparallel = false; amroutine->amkeytype = InvalidOid; @@ -337,6 +339,9 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, GISTInitBuffer(ptr->buffer, (is_leaf) ? F_LEAF : 0); ptr->page = BufferGetPage(ptr->buffer); ptr->block.blkno = BufferGetBlockNumber(ptr->buffer); + PredicateLockPageSplit(rel, + BufferGetBlockNumber(buffer), + BufferGetBlockNumber(ptr->buffer)); } /* @@ -1213,6 +1218,12 @@ gistinserttuples(GISTInsertState *state, GISTInsertStack *stack, List *splitinfo; bool is_split; + /* + * Check for any rw conflicts (in serialisation isolation level) + * just before we intend to modify the page + */ + CheckForSerializableConflictIn(state->r, NULL, stack->buffer); + /* Insert the tuple(s) to the page, splitting the page if necessary */ is_split = gistplacetopage(state->r, state->freespace, giststate, stack->buffer, diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c index b30b931c3b8..c4e8a3b9131 100644 --- a/src/backend/access/gist/gistget.c +++ b/src/backend/access/gist/gistget.c @@ -18,6 +18,8 @@ #include "access/relscan.h" #include "catalog/pg_type.h" #include "miscadmin.h" +#include "storage/lmgr.h" +#include "storage/predicate.h" #include "pgstat.h" #include "lib/pairingheap.h" #include "utils/builtins.h" @@ -336,6 +338,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances, buffer = ReadBuffer(scan->indexRelation, pageItem->blkno); LockBuffer(buffer, GIST_SHARE); + PredicateLockPage(r, BufferGetBlockNumber(buffer), scan->xs_snapshot); gistcheckpage(scan->indexRelation, buffer); page = BufferGetPage(buffer); TestForOldSnapshot(scan->xs_snapshot, r, page); |