gist-ssi.patch
text/plain
Filename: gist-ssi.patch
Type: text/plain
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
| File | + | − |
|---|---|---|
| src/backend/access/gist/gist.c | 3 | 0 |
| src/backend/access/gist/gistget.c | 2 | 0 |
| src/backend/access/gist/gistvacuum.c | 6 | 0 |
| src/backend/storage/lmgr/predicate.c | 40 | 1 |
| src/include/catalog/pg_am.h | 1 | 0 |
| src/include/storage/predicate.h | 1 | 0 |
*** a/src/backend/access/gist/gist.c
--- b/src/backend/access/gist/gist.c
***************
*** 20,25 ****
--- 20,26 ----
#include "miscadmin.h"
#include "storage/bufmgr.h"
#include "storage/indexfsm.h"
+ #include "storage/predicate.h"
#include "utils/memutils.h"
const XLogRecPtr XLogRecPtrForTemp = {1, 1};
***************
*** 286,291 **** gistplacetopage(GISTInsertState *state, GISTSTATE *giststate)
--- 287,294 ----
bool is_splitted = false;
bool is_leaf = (GistPageIsLeaf(state->stack->page)) ? true : false;
+ CheckForSerializableConflictIn(state->r, NULL, state->stack->buffer);
+
/*
* if (!is_leaf) remove old key: This node's key has been modified, either
* because a child split occurred or because we needed to adjust our key
*** a/src/backend/access/gist/gistget.c
--- b/src/backend/access/gist/gistget.c
***************
*** 20,25 ****
--- 20,26 ----
#include "miscadmin.h"
#include "pgstat.h"
#include "storage/bufmgr.h"
+ #include "storage/predicate.h"
#include "utils/memutils.h"
***************
*** 217,222 **** gistnext(IndexScanDesc scan, TIDBitmap *tbm)
--- 218,224 ----
Assert(so->curbuf != InvalidBuffer);
LockBuffer(so->curbuf, GIST_SHARE);
gistcheckpage(scan->indexRelation, so->curbuf);
+ PredicateLockPage(scan->indexRelation, BufferGetBlockNumber(so->curbuf));
p = BufferGetPage(so->curbuf);
opaque = GistPageGetOpaque(p);
*** a/src/backend/access/gist/gistvacuum.c
--- b/src/backend/access/gist/gistvacuum.c
***************
*** 23,28 ****
--- 23,29 ----
#include "storage/freespace.h"
#include "storage/indexfsm.h"
#include "storage/lmgr.h"
+ #include "storage/predicate.h"
#include "utils/memutils.h"
***************
*** 99,106 **** gistvacuumcleanup(PG_FUNCTION_ARGS)
if (PageIsNew(page) || GistPageIsDeleted(page))
{
! totFreePages++;
! RecordFreeIndexPage(rel, blkno);
}
else
lastFilledBlock = blkno;
--- 100,110 ----
if (PageIsNew(page) || GistPageIsDeleted(page))
{
! if (!PageIsPredicateLocked(rel, blkno))
! {
! totFreePages++;
! RecordFreeIndexPage(rel, blkno);
! }
}
else
lastFilledBlock = blkno;
*** a/src/backend/storage/lmgr/predicate.c
--- b/src/backend/storage/lmgr/predicate.c
***************
*** 87,93 ****
* PredicateLockShmemSize(void)
*
* predicate lock reporting
! * PredicateLockData *GetPredicateLockStatusData(void)
*
* predicate lock maintenance
* RegisterSerializableTransaction(Snapshot snapshot)
--- 87,94 ----
* PredicateLockShmemSize(void)
*
* predicate lock reporting
! * GetPredicateLockStatusData(void)
! * PageIsPredicateLocked(Relation relation, BlockNumber blkno)
*
* predicate lock maintenance
* RegisterSerializableTransaction(Snapshot snapshot)
***************
*** 727,732 **** EnsureMySerializableXidExists(void)
--- 728,771 ----
}
}
+ /*
+ * Check whether there are any predicate locks held by any transaction
+ * for the page at the given block number.
+ *
+ * Note that the transaction may be completed but not yet subject to
+ * cleanup due to overlapping serializable transactions. This must
+ * return valid information regardless of transaction isolation level.
+ *
+ * Also note that this doesn't check for a conflicting relation lock,
+ * just a lock specifically on the given page.
+ *
+ * One use is to support proper behavior during GiST index vacuum.
+ */
+ bool
+ PageIsPredicateLocked(const Relation relation, const BlockNumber blkno)
+ {
+ PREDICATELOCKTARGETTAG targettag;
+ uint32 targettaghash;
+ LWLockId partitionLock;
+ PREDICATELOCKTARGET *target;
+
+ SET_PREDICATELOCKTARGETTAG_PAGE(targettag,
+ relation->rd_node.dbNode,
+ relation->rd_id,
+ blkno);
+
+ targettaghash = PredicateLockTargetTagHashCode(&targettag);
+ partitionLock = PredicateLockHashPartitionLock(targettaghash);
+ LWLockAcquire(partitionLock, LW_SHARED);
+ target = (PREDICATELOCKTARGET *)
+ hash_search_with_hash_value(PredicateLockTargetHash,
+ &targettag, targettaghash,
+ HASH_FIND, NULL);
+ LWLockRelease(partitionLock);
+
+ return (target != NULL);
+ }
+
/*
* Check whether a particular lock is held by this transaction.
*** a/src/include/catalog/pg_am.h
--- b/src/include/catalog/pg_am.h
***************
*** 117,123 **** DESCR("b-tree index access method");
DATA(insert OID = 405 ( hash 1 1 f t f f f f f f f f 23 hashinsert hashbeginscan hashgettuple hashgetbitmap hashrescan hashendscan hashmarkpos hashrestrpos hashbuild hashbulkdelete hashvacuumcleanup hashcostestimate hashoptions ));
DESCR("hash index access method");
#define HASH_AM_OID 405
! DATA(insert OID = 783 ( gist 0 7 f f f t t t t t t f 0 gistinsert gistbeginscan gistgettuple gistgetbitmap gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbulkdelete gistvacuumcleanup gistcostestimate gistoptions ));
DESCR("GiST index access method");
#define GIST_AM_OID 783
DATA(insert OID = 2742 ( gin 0 5 f f f t t f f t f f 0 gininsert ginbeginscan - gingetbitmap ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbulkdelete ginvacuumcleanup gincostestimate ginoptions ));
--- 117,123 ----
DATA(insert OID = 405 ( hash 1 1 f t f f f f f f f f 23 hashinsert hashbeginscan hashgettuple hashgetbitmap hashrescan hashendscan hashmarkpos hashrestrpos hashbuild hashbulkdelete hashvacuumcleanup hashcostestimate hashoptions ));
DESCR("hash index access method");
#define HASH_AM_OID 405
! DATA(insert OID = 783 ( gist 0 7 f f f t t t t t t t 0 gistinsert gistbeginscan gistgettuple gistgetbitmap gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbulkdelete gistvacuumcleanup gistcostestimate gistoptions ));
DESCR("GiST index access method");
#define GIST_AM_OID 783
DATA(insert OID = 2742 ( gin 0 5 f f f t t f f t f f 0 gininsert ginbeginscan - gingetbitmap ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbulkdelete ginvacuumcleanup gincostestimate ginoptions ));
*** a/src/include/storage/predicate.h
--- b/src/include/storage/predicate.h
***************
*** 156,161 **** extern Size PredicateLockShmemSize(void);
--- 156,162 ----
/* predicate lock reporting */
extern PredicateLockData *GetPredicateLockStatusData(void);
+ extern bool PageIsPredicateLocked(const Relation relation, const BlockNumber blkno);
/* predicate lock maintenance */
extern void RegisterSerializableTransaction(const Snapshot snapshot);