/* *TheLOCKTAGstructisdefinedwithmaliceaforethoughttofitinto16 *byteswithnopadding.Notethatthiswouldneedadjustmentifwewere *towidenOid,BlockNumber,orTransactionIdtomorethan32bits. * *Weincludelockmethodidinthelocktagsothatasinglehashtablein *sharedmemorycanstorelocksofdifferentlockmethods.
*/ typedefstruct LOCKTAG
{
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 */
uint8 locktag_type; /* see enum LockTagType */
uint8 locktag_lockmethodid; /* lockmethod indicator */
} LOCKTAG;
/* ID info for a relation is DB OID + REL OID; DB OID = 0 if shared */ #define SET_LOCKTAG_RELATION(locktag,dboid,reloid) \
((locktag).locktag_field1 = (dboid), \
(locktag).locktag_field2 = (reloid), \
(locktag).locktag_field3 = 0, \
(locktag).locktag_field4 = 0, \
(locktag).locktag_type = LOCKTAG_RELATION, \
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
/* same ID info as RELATION */ #define SET_LOCKTAG_RELATION_EXTEND(locktag,dboid,reloid) \
((locktag).locktag_field1 = (dboid), \
(locktag).locktag_field2 = (reloid), \
(locktag).locktag_field3 = 0, \
(locktag).locktag_field4 = 0, \
(locktag).locktag_type = LOCKTAG_RELATION_EXTEND, \
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
/* ID info for frozen IDs is DB OID */ #define SET_LOCKTAG_DATABASE_FROZEN_IDS(locktag,dboid) \
((locktag).locktag_field1 = (dboid), \
(locktag).locktag_field2 = 0, \
(locktag).locktag_field3 = 0, \
(locktag).locktag_field4 = 0, \
(locktag).locktag_type = LOCKTAG_DATABASE_FROZEN_IDS, \
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
/* ID info for a page is RELATION info + BlockNumber */ #define SET_LOCKTAG_PAGE(locktag,dboid,reloid,blocknum) \
((locktag).locktag_field1 = (dboid), \
(locktag).locktag_field2 = (reloid), \
(locktag).locktag_field3 = (blocknum), \
(locktag).locktag_field4 = 0, \
(locktag).locktag_type = LOCKTAG_PAGE, \
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
/* ID info for a tuple is PAGE info + OffsetNumber */ #define SET_LOCKTAG_TUPLE(locktag,dboid,reloid,blocknum,offnum) \
((locktag).locktag_field1 = (dboid), \
(locktag).locktag_field2 = (reloid), \
(locktag).locktag_field3 = (blocknum), \
(locktag).locktag_field4 = (offnum), \
(locktag).locktag_type = LOCKTAG_TUPLE, \
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
/* ID info for a transaction is its TransactionId */ #define SET_LOCKTAG_TRANSACTION(locktag,xid) \
((locktag).locktag_field1 = (xid), \
(locktag).locktag_field2 = 0, \
(locktag).locktag_field3 = 0, \
(locktag).locktag_field4 = 0, \
(locktag).locktag_type = LOCKTAG_TRANSACTION, \
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
/* ID info for a virtual transaction is its VirtualTransactionId */ #define SET_LOCKTAG_VIRTUALTRANSACTION(locktag,vxid) \
((locktag).locktag_field1 = (vxid).procNumber, \
(locktag).locktag_field2 = (vxid).localTransactionId, \
(locktag).locktag_field3 = 0, \
(locktag).locktag_field4 = 0, \
(locktag).locktag_type = LOCKTAG_VIRTUALTRANSACTION, \
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
/* data */
LOCKMASK grantMask; /* bitmask for lock types already granted */
LOCKMASK waitMask; /* bitmask for lock types awaited */
dlist_head procLocks; /* list of PROCLOCK objects assoc. with lock */
dclist_head waitProcs; /* list of PGPROC objects waiting on lock */ int requested[MAX_LOCKMODES]; /* counts of requested locks */ int nRequested; /* total of requested[] array */ int granted[MAX_LOCKMODES]; /* counts of granted locks */ int nGranted; /* total of granted[] array */
} LOCK;
/* *Wemayhaveseveraldifferentbackendsholdingorawaitinglocks *onthesamelockableobject.Weneedtostoresomeper-holder/waiter *informationforeachsuchholder(orwould-beholder).Thisiskeptin *aPROCLOCKstruct. * *PROCLOCKTAGisthekeyinformationneededtolookupaPROCLOCKiteminthe *proclockhashtable.APROCLOCKTAGvalueuniquelyidentifiesthecombination *ofalockableobjectandaholder/waiterforthatobject.(Wecanuse *pointersherebecausethePROCLOCKTAGneedonlybeuniqueforthelifespan *ofthePROCLOCK,anditwillneveroutlivethelockortheproc.) * *Internallytoabackend,itispossibleforthesamelocktobeheld *fordifferentpurposes:thebackendtrackstransactionlocksseparately *fromsessionlocks.However,thisisnotreflectedintheshared-memory *state:weonlytrackwhichbackend(s)holdthelock.ThisisOKsincea *backendcanneverblockitself. * *TheholdMaskfieldshowsthealready-grantedlocksrepresentedbythis *proclock.Notethattherewillbeaproclockobject,possiblywith *zeroholdMask,foranylockthattheprocessiscurrentlywaitingon. *Otherwise,proclockobjectswhoseholdMasksarezeroarerecycled *assoonasconvenient. * *releaseMaskisworkspaceforLockReleaseAll():itshowsthelocksdue *tobereleasedduringthecurrentcall.Thismustonlybeexaminedor *setbythebackendowningthePROCLOCK. * *EachPROCLOCKobjectislinkedintolistsforboththeassociatedLOCK *objectandtheowningPGPROCobject.NotethatthePROCLOCKisentered *intotheselistsassoonasitiscreated,evenifnolockhasyetbeen *granted.APGPROCthatiswaitingforalocktobegrantedwillalsobe *linkedintothelock'swaitProcsqueue.
*/ typedefstruct PROCLOCKTAG
{ /* NB: we assume this struct contains no padding! */
LOCK *myLock; /* link to per-lockable-object information */
PGPROC *myProc; /* link to PGPROC of owning backend */
} PROCLOCKTAG;
typedefstruct PROCLOCK
{ /* tag */
PROCLOCKTAG tag; /* unique identifier of proclock object */
/* data */
PGPROC *groupLeader; /* proc's lock group leader, or proc itself */
LOCKMASK holdMask; /* bitmask for lock types currently held */
LOCKMASK releaseMask; /* bitmask for lock types to be released */
dlist_node lockLink; /* list link in LOCK's list of proclocks */
dlist_node procLink; /* list link in PGPROC's list of proclocks */
} PROCLOCK;
typedefstruct LOCALLOCKOWNER
{ /* *Note:ifownerisNULLthenthelockisheldonbehalfofthesession; *otherwiseitisheldonbehalfofmycurrenttransaction. * *Mustuseaforwardstructreferencetoavoidcircularity.
*/ struct ResourceOwnerData *owner;
int64 nLocks; /* # of times held by this owner */
} LOCALLOCKOWNER;
typedefstruct LOCALLOCK
{ /* tag */
LOCALLOCKTAG tag; /* unique identifier of locallock entry */
/* data */
uint32 hashcode; /* copy of LOCKTAG's hash value */
LOCK *lock; /* associated LOCK object, if any */
PROCLOCK *proclock; /* associated PROCLOCK object, if any */
int64 nLocks; /* total number of times lock is held */ int numLockOwners; /* # of relevant ResourceOwners */ int maxLockOwners; /* allocated size of array */
LOCALLOCKOWNER *lockOwners; /* dynamically resizable array */ bool holdsStrongLockCount; /* bumped FastPathStrongRelationLocks */ bool lockCleared; /* we read all sinval msgs for lock */
} LOCALLOCK;
typedefstruct LockInstanceData
{
LOCKTAG locktag; /* tag for locked object */
LOCKMASK holdMask; /* locks held by this PGPROC */
LOCKMODE waitLockMode; /* lock awaited by this PGPROC, if any */
VirtualTransactionId vxid; /* virtual transaction ID of this PGPROC */
TimestampTz waitStart; /* time at which this PGPROC started waiting
* for lock */ int pid; /* pid of this PGPROC */ int leaderPid; /* pid of group leader; = pid if no group */ bool fastpath; /* taken via fastpath? */
} LockInstanceData;
typedefstruct LockData
{ int nelements; /* The length of the array */
LockInstanceData *locks; /* Array of per-PROCLOCK information */
} LockData;
typedefstruct BlockedProcData
{ int pid; /* pid of a blocked PGPROC */ /* Per-PROCLOCK information about PROCLOCKs of the lock the pid awaits */ /* (these fields refer to indexes in BlockedProcsData.locks[]) */ int first_lock; /* index of first relevant LockInstanceData */ int num_locks; /* number of relevant LockInstanceDatas */ /* PIDs of PGPROCs that are ahead of "pid" in the lock's wait queue */ /* (these fields refer to indexes in BlockedProcsData.waiter_pids[]) */ int first_waiter; /* index of first preceding waiter */ int num_waiters; /* number of preceding waiters */
} BlockedProcData;
typedefstruct BlockedProcsData
{
BlockedProcData *procs; /* Array of per-blocked-proc information */
LockInstanceData *locks; /* Array of per-PROCLOCK information */ int *waiter_pids; /* Array of PIDs of other blocked PGPROCs */ int nprocs; /* # of valid entries in procs[] array */ int maxprocs; /* Allocated length of procs[] array */ int nlocks; /* # of valid entries in locks[] array */ int maxlocks; /* Allocated length of locks[] array */ int npids; /* # of valid entries in waiter_pids[] array */ int maxpids; /* Allocated length of waiter_pids[] array */
} BlockedProcsData;
/* Result codes for LockAcquire() */ typedefenum
{
LOCKACQUIRE_NOT_AVAIL, /* lock not available, and dontWait=true */
LOCKACQUIRE_OK, /* lock successfully acquired */
LOCKACQUIRE_ALREADY_HELD, /* incremented count for lock already held */
LOCKACQUIRE_ALREADY_CLEAR, /* incremented count for lock already clear */
} LockAcquireResult;
/* Deadlock states identified by DeadLockCheck() */ typedefenum
{
DS_NOT_YET_CHECKED, /* no deadlock check has run yet */
DS_NO_DEADLOCK, /* no deadlock detected */
DS_SOFT_DEADLOCK, /* deadlock avoided by queue rearrangement */
DS_HARD_DEADLOCK, /* deadlock, no way out but ERROR */
DS_BLOCKED_BY_AUTOVACUUM, /* no deadlock; queue blocked by autovacuum
* worker */
} DeadLockState;
/* Lock a VXID (used to wait for a transaction to finish) */ externvoid VirtualXactLockTableInsert(VirtualTransactionId vxid); externvoid VirtualXactLockTableCleanup(void); externbool VirtualXactLock(VirtualTransactionId vxid, bool wait);
#endif/* LOCK_H_ */
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.19 Sekunden
(vorverarbeitet am 2026-08-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.