Skip to content

Commit 3ad5586

Browse files
committed
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
1 parent 4b9094e commit 3ad5586

File tree

6 files changed

+795
-3
lines changed

6 files changed

+795
-3
lines changed

src/backend/access/gist/gist.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "access/gistscan.h"
1919
#include "catalog/pg_collation.h"
2020
#include "miscadmin.h"
21+
#include "storage/lmgr.h"
22+
#include "storage/predicate.h"
2123
#include "nodes/execnodes.h"
2224
#include "utils/builtins.h"
2325
#include "utils/index_selfuncs.h"
@@ -70,7 +72,7 @@ gisthandler(PG_FUNCTION_ARGS)
7072
amroutine->amsearchnulls = true;
7173
amroutine->amstorage = true;
7274
amroutine->amclusterable = true;
73-
amroutine->ampredlocks = false;
75+
amroutine->ampredlocks = true;
7476
amroutine->amcanparallel = false;
7577
amroutine->amkeytype = InvalidOid;
7678

@@ -337,6 +339,9 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
337339
GISTInitBuffer(ptr->buffer, (is_leaf) ? F_LEAF : 0);
338340
ptr->page = BufferGetPage(ptr->buffer);
339341
ptr->block.blkno = BufferGetBlockNumber(ptr->buffer);
342+
PredicateLockPageSplit(rel,
343+
BufferGetBlockNumber(buffer),
344+
BufferGetBlockNumber(ptr->buffer));
340345
}
341346

342347
/*
@@ -1213,6 +1218,12 @@ gistinserttuples(GISTInsertState *state, GISTInsertStack *stack,
12131218
List *splitinfo;
12141219
bool is_split;
12151220

1221+
/*
1222+
* Check for any rw conflicts (in serialisation isolation level)
1223+
* just before we intend to modify the page
1224+
*/
1225+
CheckForSerializableConflictIn(state->r, NULL, stack->buffer);
1226+
12161227
/* Insert the tuple(s) to the page, splitting the page if necessary */
12171228
is_split = gistplacetopage(state->r, state->freespace, giststate,
12181229
stack->buffer,

src/backend/access/gist/gistget.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "access/relscan.h"
1919
#include "catalog/pg_type.h"
2020
#include "miscadmin.h"
21+
#include "storage/lmgr.h"
22+
#include "storage/predicate.h"
2123
#include "pgstat.h"
2224
#include "lib/pairingheap.h"
2325
#include "utils/builtins.h"
@@ -336,6 +338,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
336338

337339
buffer = ReadBuffer(scan->indexRelation, pageItem->blkno);
338340
LockBuffer(buffer, GIST_SHARE);
341+
PredicateLockPage(r, BufferGetBlockNumber(buffer), scan->xs_snapshot);
339342
gistcheckpage(scan->indexRelation, buffer);
340343
page = BufferGetPage(buffer);
341344
TestForOldSnapshot(scan->xs_snapshot, r, page);

src/backend/storage/lmgr/README-SSI

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,10 +374,11 @@ however, a search discovers that no root page has yet been created, a
374374
predicate lock on the index relation is required.
375375

376376
* GiST searches can determine that there are no matches at any
377-
level of the index, so there must be a predicate lock at each index
377+
level of the index, so we acquire predicate lock at each index
378378
level during a GiST search. An index insert at the leaf level can
379379
then be trusted to ripple up to all levels and locations where
380-
conflicting predicate locks may exist.
380+
conflicting predicate locks may exist. In case there is a page split,
381+
we need to copy predicate lock from an original page to all new pages.
381382

382383
* The effects of page splits, overflows, consolidations, and
383384
removals must be carefully reviewed to ensure that predicate locks

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy