diff --git a/src/include/storage/predicate.h b/src/include/storage/predicate.h index d071c21..7dcc2af 100644 --- a/src/include/storage/predicate.h +++ b/src/include/storage/predicate.h @@ -1,7 +1,7 @@ /*------------------------------------------------------------------------- * * predicate.h - * POSTGRES predicate locking definitions. + * POSTGRES public predicate locking definitions. * * * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group @@ -14,137 +14,15 @@ #ifndef PREDICATE_H #define PREDICATE_H -#include "access/htup.h" -#include "storage/lock.h" #include "utils/relcache.h" #include "utils/snapshot.h" -/* GUC variables */ + +/* + * GUC variables + */ extern int max_predicate_locks_per_xact; -/* - * The SERIALIZABLEXACTTAG struct identifies a serializable transaction. - */ -typedef struct SERIALIZABLEXACTTAG -{ - VirtualTransactionId vxid; /* We always have one of these. */ -} SERIALIZABLEXACTTAG; - -/* - * Information needed for each serializable database transaction to support SSI techniques. - * TODO SSI: Should inConflict and outConflict be lists? That would allow us to reduce - * false positives, *and* would allow us to guarantee that an immediate retry - * of a transaction would never fail on the exact same conflicts. - * The RAM doesn't look like it would be the limiting factor, but CPU time might - * be -- we should have baseline benchmarks before attempting this. - */ -typedef struct SERIALIZABLEXACT -{ - /* hash key */ - SERIALIZABLEXACTTAG tag; - - /* data */ - struct SERIALIZABLEXACT *outConflict; /* ptr to write transaction - * whose data we couldn't - * read. invalid means no - * conflict; self-reference - * means multiple or - * committed. */ - struct SERIALIZABLEXACT *inConflict; /* ptr to read transaction - * which couldn't see our - * write. invalid means no - * conflict; self-reference - * means multiple or - * committed. */ - TransactionId topXid; /* top level xid for the transaction, if one - * exists */ - TransactionId finishedBefore; /* invalid means still running; else - * the struct expires when no tags < - * this. */ - TransactionId xmin; /* the transaction's snapshot xmin */ - SHM_QUEUE predicateLocks; /* list of associated PREDICATELOCK objects */ - SHM_QUEUE xids; /* list of associated SERIALIZABLEXID objects */ - SHM_QUEUE finishedLink; /* list link in - * FinishedSerializableTransactions */ - bool rolledBack; /* ignore conflicts when true; allows deferred - * cleanup */ -} SERIALIZABLEXACT; - - -typedef enum PredicateLockTargetType -{ - PREDLOCKTAG_RELATION, - PREDLOCKTAG_PAGE, - PREDLOCKTAG_TUPLE - /* TODO Other types may be needed for index locking */ -} PredicateLockTargetType; - -/* - * The PREDICATELOCKTARGETTAG struct is defined to fit into 16 - * bytes with no padding. Note that this would need adjustment if we were - * to widen Oid or BlockNumber to more than 32 bits. - */ -typedef struct PREDICATELOCKTARGETTAG -{ - uint32 locktag_field1; /* a 32-bit ID field */ - uint32 locktag_field2; /* a 32-bit ID field */ - uint32 locktag_field3; /* a 32-bit ID field */ - uint16 locktag_field4; /* a 16-bit ID field */ - uint16 locktag_field5; /* a 16-bit ID field */ -} PREDICATELOCKTARGETTAG; - -/* - * These macros define how we map logical IDs of lockable objects into - * the physical fields of PREDICATELOCKTARGETTAG. Use these to set up values, - * rather than accessing the fields directly. Note multiple eval of target! - * - * TODO SSI: If we always use the same fields for the same type of value, - * we should rename these. Holding off until it's clear there are no exceptions. - * Since indexes are relations with blocks and tuples, it's looking likely that - * the rename will be possible. If not, we may need to divide the last field - * and use part of it for a target type, so that we know how to interpret the - * data.. - */ -#define SET_PREDICATELOCKTARGETTAG_RELATION(locktag,dboid,reloid) \ - ((locktag).locktag_field1 = (dboid), \ - (locktag).locktag_field2 = (reloid), \ - (locktag).locktag_field3 = InvalidBlockNumber, \ - (locktag).locktag_field4 = InvalidOffsetNumber, \ - (locktag).locktag_field5 = 0) - -#define SET_PREDICATELOCKTARGETTAG_PAGE(locktag,dboid,reloid,blocknum) \ - ((locktag).locktag_field1 = (dboid), \ - (locktag).locktag_field2 = (reloid), \ - (locktag).locktag_field3 = (blocknum), \ - (locktag).locktag_field4 = InvalidOffsetNumber, \ - (locktag).locktag_field5 = 0) - -#define SET_PREDICATELOCKTARGETTAG_TUPLE(locktag,dboid,reloid,blocknum,offnum) \ - ((locktag).locktag_field1 = (dboid), \ - (locktag).locktag_field2 = (reloid), \ - (locktag).locktag_field3 = (blocknum), \ - (locktag).locktag_field4 = (offnum), \ - (locktag).locktag_field5 = 0) - -#define GET_PREDICATELOCKTARGETTAG_DB(locktag) \ - ((locktag).locktag_field1) -#define GET_PREDICATELOCKTARGETTAG_RELATION(locktag) \ - ((locktag).locktag_field2) -#define GET_PREDICATELOCKTARGETTAG_PAGE(locktag) \ - ((locktag).locktag_field3) -#define GET_PREDICATELOCKTARGETTAG_OFFSET(locktag) \ - ((locktag).locktag_field4) -#define GET_PREDICATELOCKTARGETTAG_TYPE(locktag) \ - (((locktag).locktag_field4 != InvalidOffsetNumber) ? PREDLOCKTAG_TUPLE : \ - (((locktag).locktag_field3 != InvalidBlockNumber) ? PREDLOCKTAG_PAGE : \ - PREDLOCKTAG_RELATION)) - -typedef struct PredicateLockData -{ - int nelements; - PREDICATELOCKTARGETTAG *locktags; - SERIALIZABLEXACT *xacts; -} PredicateLockData; /* * function prototypes @@ -155,7 +33,6 @@ extern void InitPredicateLocks(void); extern Size PredicateLockShmemSize(void); /* predicate lock reporting */ -extern PredicateLockData *GetPredicateLockStatusData(void); extern bool PageIsPredicateLocked(const Relation relation, const BlockNumber blkno); /* predicate lock maintenance */