mirror of
https://github.com/postgres/postgres.git
synced 2025-06-13 07:41:39 +03:00
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
This commit is contained in:
@ -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,
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user